如何刷新DbContext

我想刷新我的DbContext所有实体而不重新创build它,我尝试了以下,没有一个是合理的:

 var context = ((IObjectContextAdapter)myDbContext).ObjectContext; var refreshableObjects = (from entry in context.ObjectStateManager.GetObjectStateEntries( EntityState.Added | EntityState.Deleted | EntityState.Modified | EntityState.Unchanged) where entry.EntityKey != null select entry.Entity); context.Refresh(RefreshMode.StoreWins, refreshableObjects); //....................................................................... foreach (var entry in this.Orm.ChangeTracker.Entries()) { entry.State = EntityState.Unchanged; } this.Orm.ChangeTracker.DetectChanges(); 

唯一一个刷新我的DbContext

 foreach (var i in this.Orm.ChangeTracker.Entries()) i.Reload(); 

但是太慢了。 你能帮我select正确的方法吗?

我刚刚发现Enumerable结果应该被评估,因为Refresh方法将它作为对象并且不计算它。

 var context = ((IObjectContextAdapter)myDbContext).ObjectContext; var refreshableObjects = (from entry in context.ObjectStateManager.GetObjectStateEntries( EntityState.Added | EntityState.Deleted | EntityState.Modified | EntityState.Unchanged) where entry.EntityKey != null select entry.Entity).ToList(); context.Refresh(RefreshMode.StoreWins, refreshableObjects); 

我更喜欢以下内容:

 var refreshableObjects = myDbContext.ChangeTracker.Entries().Select(c=>c.Entity).ToList(); context.Refresh(RefreshMode.StoreWins, refreshableObjects); 

我检查了这一点,ID工作正常:

 //Search Box box = dbContext.Boxes.FirstOrDefault(x => x.BoxId == 45); //breakpoint here, change Name of Box by sql management studio //Refresh var context = ((IObjectContextAdapter)dbContext).ObjectContext; context.Refresh(System.Data.Entity.Core.Objects.RefreshMode.StoreWins, box); //Check refresh and if it is in context box = dbContext.Boxes.FirstOrDefault(x => x.BoxId == 45); 

你确定它是相同的数据库上下文吗?

 using System.Data.Entity.Core.Objects; using System.Data.Entity.Infrastructure; using System.Linq; namespace System.Data.Entity { public static class DbContextExtensions { /// <summary> /// Refresh non-detached entities /// </summary> /// <param name="dbContext">context of the entities</param> /// <param name="refreshMode">store or client wins</param> /// <param name="entityType">when specified only entities of that type are refreshed. when null all non-detached entities are modified</param> /// <returns></returns> public static DbContext RefreshEntites(this DbContext dbContext, RefreshMode refreshMode, Type entityType) { //https://christianarg.wordpress.com/2013/06/13/entityframework-refreshall-loaded-entities-from-database/ var objectContext = ((IObjectContextAdapter)dbContext).ObjectContext; var refreshableObjects = objectContext.ObjectStateManager .GetObjectStateEntries(EntityState.Added | EntityState.Deleted | EntityState.Modified | EntityState.Unchanged) .Where(x => entityType == null || x.Entity.GetType() == entityType) .Where(entry => entry.EntityKey != null) .Select(e => e.Entity) .ToArray(); objectContext.Refresh(RefreshMode.StoreWins, refreshableObjects); return dbContext; } public static DbContext RefreshAllEntites(this DbContext dbContext, RefreshMode refreshMode) { return RefreshEntites(dbContext: dbContext, refreshMode: refreshMode, entityType: null); //null entityType is a wild card } public static DbContext RefreshEntites<TEntity>(this DbContext dbContext, RefreshMode refreshMode) { return RefreshEntites(dbContext: dbContext, refreshMode: refreshMode, entityType: typeof(TEntity)); } } } 

在某些情况下,如果某个集合已被第三方应用程序更新,则在刷新集合对象时,该集合可能不会被重新加载。

我有这样的情况,我有一个对象A与对象B的一对多关系。

应用程序1将A.ListB装入一个空的对象A. 应用程序2填充A.ListB集合。 应用程序1重新加载对象A.

通过上面的解决scheme,A.ListB保持空白。 我不得不明确地重新加载A.ListB集合。

这是一个通用的方式来重新加载所有的集合:

 var context = ((IObjectContextAdapter)this).ObjectContext; // detach all added entities ChangeTracker.Entries().Where(e => e.State == EntityState.Added).ToList().ForEach(e => e.State = EntityState.Detached); // select entities var refreshableObjects = ChangeTracker.Entries().Select(e => e.Entity).ToList(); // refresh each refreshable object foreach (var @object in refreshableObjects) { // refresh each collection of the object context.ObjectStateManager.GetRelationshipManager(@object).GetAllRelatedEnds().Where( r => r.IsLoaded).ToList().ForEach( c => c.Load() ); // refresh the object context.Refresh(RefreshMode.StoreWins, @object); }