我遇到的情况是,我基本上需要将一对多关联的子实体的更改写入数据库,但不保存对父实体所做的任何更改。
实体框架目前处理上下文范围(EntityContext.SaveChanges())中的数据库提交,这对于强制执行关系等是有意义的。但我想知道是否有一些最佳实践或者可能是推荐的方法关于对个人entite而不是整个上下文进行细粒度数据库提交。
答案 0 :(得分:8)
最佳做法?除此之外,你的意思是“不要这样做!”?
我认为没有一种最佳做法可以使ObjectContext与数据库的状态不同。
如果你必须这样做,我会新建一个新的ObjectContext并在那里对子实体进行更改。这样,两种情境都是一致的。
答案 1 :(得分:4)
我有类似的需求。我正在考虑的解决方案是在所有实体上实现包装器属性,这些实体私下存储任何属性更改,而不会影响实际的实体属性。然后,我将向实体添加一个SaveChanges()方法,该方法将更改写入实体,然后在上下文中调用SaveChanges()。
这种方法的问题在于您需要使所有实体都符合此模式。但是,它似乎工作得很好。它确实有另一个缺点,如果你对包含大量数据的很多对象进行了很多更改,你最终会在内存中留下无关的副本。
我能想到的唯一其他解决方案是,在保存更改后,保存所有已更改/添加/删除的实体的实体状态,将它们设置为未修改,除了您要更改的实体,保存更改,然后还原其他实体的状态。但这听起来可能很慢。
答案 2 :(得分:2)
这可以通过使用AcceptAllChanges()来完成。
对父实体进行更改,调用AcceptAllChanges(),然后对相关实体进行更改并调用SaveChanges()。您对父项所做的更改将不会保存,因为它们已“提交”到实体但未保存到数据库中。
using (AdventureWorksEntities adv = new AdventureWorksEntities())
{
var completeHeader = (from o in adv.SalesOrderHeader.Include("SalesOrderDetail")
where o.DueDate > System.DateTime.Now
select o).First();
completeHeader.ShipDate = System.DateTime.Now;
adv.AcceptAllChanges();
var details = completeHeader.SalesOrderDetail.Where(x => x.UnitPrice > 10.0m);
foreach (SalesOrderDetail d in details)
{
d.UnitPriceDiscount += 5.0m;
}
adv.SaveChanges();
}