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 (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
