entity-framework – 通用存储库来更新整个聚合
我正在使用存储库模式来提供对我的聚合的访问和保存.
问题是更新由实体关系组成的聚合. 例如,采取Order和OrderItem关系.聚合根是管理自己的OrderItem集合的Order.因此,OrderRepository将负责更新整个聚合(不会有OrderItemRepository). 数据持久性使用实体框架6进行处理. 更新存储库方法(DbContext.SaveChanges()发生在别处): public void Update(TDataEntity item) { var entry = context.Entry<TDataEntity>(item); if (entry.State == EntityState.Detached) { var set = context.Set<TDataEntity>(); TDataEntity attachedEntity = set.Local.SingleOrDefault(e => e.Id.Equals(item.Id)); if (attachedEntity != null) { // If the identity is already attached,rather set the state values var attachedEntry = context.Entry(attachedEntity); attachedEntry.CurrentValues.SetValues(item); } else { entry.State = EntityState.Modified; } } } 在我上面的例子中,只有Order实体才会被更新,而不是相关的OrderItem集合. 我必须附加所有的OrderItem实体吗?我怎么能这样做呢?
Julie Lerman给出了一个很好的方式来处理如何更新她的书籍
Programming Entity Framework: DbContext中的整个聚合.
她写道:
这种技术叫做画状态. 主要有两种方法: >通过图形迭代,使用您对模型的知识,并为每个实体设置状态 第二个选项是非常好的,它包括创建一个界面,您的模型中的每个实体都将实现. Julie使用一个IObjectWithState接口来告诉实体的当前状态: public interface IObjectWithState { State State { get; set; } } public enum State { Added,Unchanged,Modified,Deleted } 首先要做的是通过挂起在Context类中添加构造函数的事件自动设置为从DB检索的每个实体不变: public YourContext() { ((IObjectContextAdapter)this).ObjectContext .ObjectMaterialized += (sender,args) => { var entity = args.Entity as IObjectWithState; if (entity != null) { entity.State = State.Unchanged; } }; } 然后更改您的Order和OrderItem类以实现IObjectWithState接口,并调用接受根实体的ApplyChanges方法作为参数: private static void ApplyChanges<TEntity>(TEntity root) where TEntity : class,IObjectWithState { using (var context = new YourContext()) { context.Set<TEntity>().Add(root); CheckForEntitiesWithoutStateInterface(context); foreach (var entry in context.ChangeTracker .Entries<IObjectWithState>()) { IObjectWithState stateInfo = entry.Entity; entry.State = ConvertState(stateInfo.State); } context.SaveChanges(); } } private static void CheckForEntitiesWithoutStateInterface(YourContext context) { var entitiesWithoutState = from e in context.ChangeTracker.Entries() where !(e.Entity is IObjectWithState) select e; if (entitiesWithoutState.Any()) { throw new NotSupportedException("All entities must implement IObjectWithState"); } } 最后但并非最不重要的是,不要忘了在调用ApplyChanges之前设置图形的正确状态;-)(甚至可以在同一个图形中混合修改和删除的状态) 朱莉建议在他的书中更进一步:
但是,由于我的答案已经太久了,如果你想了解更多,请去看她的book (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |