How to Refresh DbContext
我想刷新我的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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(); |
而唯一的刷新我的
1 2 | foreach (var i in this.Orm.ChangeTracker.Entries()) i.Reload(); |
但这太慢了。 您能帮我选择正确的方法吗?
我只是发现应该对
1 2 3 4 5 6 7 8 9 10 | 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); |
我更喜欢以下内容:
1 2 | var refreshableObjects = myDbContext.ChangeTracker.Entries().Select(c=>c.Entity).ToList(); context.Refresh(RefreshMode.StoreWins, refreshableObjects); |
我检查了一下,id工作正常:
1 2 3 4 5 6 7 8 9 10 11 | //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); |
您确定它是相同的数据库上下文吗?
在某些情况下,如果某个集合已由第三方应用程序更新,则刷新该集合的对象时可能不会重新加载该集合。
我遇到的情况是,我的对象A与对象B具有一对多的关系。
应用程序1加载A.ListB为空的对象A。
应用程序2填充A.ListB集合。
应用程序1重新加载对象A。
使用上述解决方案,A.ListB保持为空。我必须显式重新加载集合A.ListB。
这是重新加载所有集合的一种通用方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | 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)); } } } |
在数据库中插入后,我有一个触发器,并且正在事务中进行操作,因此我需要在相同的上下文中获取由触发器生成的新值。这为我工作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | using (var ctx = new context()) { ctx.Connection.Open(); ctx.Transaction = ctx.Connection.BeginTransaction(); ctx.Entities.InsertOnSubmit(itemDB); ctx.SubmitChanges(); ctx.Refresh(RefreshMode.OverwriteCurrentValues, itemDB); Model newModel = itemDB.ToModel(); ctx.Transaction.Commit(); return newModel; } catch (Exception ex) { ctx.Transaction.Rollback(); } |