c# – 实体框架6:检测关系变化
发布时间:2020-12-15 08:23:46 所属栏目:百科 来源:网络整理
导读:在我的DbContext子类中,我重写了SaveChanges()方法,因此我可以实现一种类似触发器的功能(在实际保存更改之前). 现在,在某些触发器中,有必要检测某些关系是否已经改变,无论多对多,一对一/零等. 我已经阅读了互联网上的一些帖子,包括本网站上的一些帖子,提到Db
在我的DbContext子类中,我重写了SaveChanges()方法,因此我可以实现一种类似触发器的功能(在实际保存更改之前).
现在,在某些触发器中,有必要检测某些关系是否已经改变,无论多对多,一对一/零等. 我已经阅读了互联网上的一些帖子,包括本网站上的一些帖子,提到DbContext API没有公开任何获取关系信息的方法. 我的SaveChanges方法: public override int SaveChanges() { IEntity entity; ChangeTracker.DetectChanges(); var stateManager = ((IObjectContextAdapter)this).ObjectContext.ObjectStateManager; var added = stateManager.GetObjectStateEntries(EntityState.Added).ToList(); var updated = stateManager.GetObjectStateEntries(EntityState.Modified).ToList(); var deleted = stateManager.GetObjectStateEntries(EntityState.Deleted).ToList(); var unchanged = stateManager.GetObjectStateEntries(EntityState.Unchanged).ToList(); while ((entity = _entitiesRequiringTriggering.FirstOrDefault(x => x.Value).Key) != null) { _entitiesRequiringTriggering[entity] = false; var entry = ChangeTracker.Entries<IEntity>().SingleOrDefault(x => x.State != EntityState.Unchanged && x.Entity == entity); if (entry == null) continue; var trigger = Triggers.Triggers.GetTriggerForEntity(entry.Entity,this); if (trigger == null) continue; trigger.BeforeSave(entry.Entity); switch (entry.State) { case EntityState.Added: trigger.BeforeAdd(entry.Entity); break; case EntityState.Modified: trigger.BeforeUpdate(entry.Entity); break; case EntityState.Deleted: trigger.BeforeDelete(entry.Entity); break; } } return base.SaveChanges(); } 请注意添加,更新,删除和更改的四个变量. 我在测试应用程序中运行以下代码: using (var db = container.Resolve<IDatabaseContext>()) { var cus = db.Query<Customer>().Single(x => x.Id == 1); var newAddress = db.Query<Address>().Single(x => x.Id == 5); cus.Address = newAddress; //also sets the foreign key property Customer.AddressId to its new corresponding value db.SaveChanges(); } 当我在调用后检查SaveChanges中的代码时,我得到了预期的结果: 我需要能够在关系发生变化时如前所述进行检测. var changed = DbEntry.Property(x => x.Name).OriginalValue == DbEntry.Property(x => x.Name).CurrentValue; 但对于不明显起作用的参考属性. 解决方法
您可以使用此ExtensionMethod获取已更改的关系列表
public static class DbContextExtensions { public static IEnumerable<Tuple<object,object>> GetRelationships( this DbContext context) { return GetAddedRelationships(context) .Union(GetDeletedRelationships(context)); } public static IEnumerable<Tuple<object,object>> GetAddedRelationships( this DbContext context) { return GetRelationships(context,EntityState.Added,(e,i) => e.CurrentValues[i]); } public static IEnumerable<Tuple<object,object>> GetDeletedRelationships( this DbContext context) { return GetRelationships(context,EntityState.Deleted,i) => e.OriginalValues[i]); } private static IEnumerable<Tuple<object,object>> GetRelationships( this DbContext context,EntityState relationshipState,Func<ObjectStateEntry,int,object> getValue) { context.ChangeTracker.DetectChanges(); var objectContext = ((IObjectContextAdapter)context).ObjectContext; return objectContext.ObjectStateManager .GetObjectStateEntries(relationshipState) .Where(e => e.IsRelationship) .Select( e => Tuple.Create( objectContext.GetObjectByKey((EntityKey)getValue(e,0)),objectContext.GetObjectByKey((EntityKey)getValue(e,1)))); } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |