2009-08-19 77 views
3

我遇到了一个场景,我基本上需要将一对多关联的子实体的更改写入数据库,但不保存对所做更改父实体。保存单个实体而不是整个上下文

实体框架当前处理上下文范围(EntityContext.SaveChanges())中的数据库提交,这对于执行关系等有意义。但是,我想知道是否存在一些最佳实践或可能是推荐的方法去做单个实体的细粒度数据库提交而不是整个上下文。

+1

我还没有看到一个办法做到这一点那么远,而且很可能是正确的。你在找什么可能会导致数据不一致。 – ADB 2009-08-19 17:38:18

回答

7

最佳做法?你的意思是,除此之外,“不要这样做!”?

我不认为有一个最佳做法使ObjectContext不同于数据库的状态。

如果您必须这样做,我会新建一个新的ObjectContext并对其中的子实体进行更改。这样,两种情况都是一致的。

+2

使用独立的上下文是一个很好的方法。过程基本上是:1)创建另一个ObjectContext的并附加连接子对象存在2)设置父导航属性3的的EntityKey)保存新的上下文,然后分离子4)将孩子“主”上下文 – dkr88 2009-08-25 16:15:10

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(); 
} 
+1

使得感觉 - 但是如果我仍然需要跟踪,然后committ更改到父对象我会失去这样做,这样做AcceptAllChanges()后的能力(正确吗?) – dkr88 2009-08-20 21:51:39

4

我有类似的需求。我正在考虑的解决方案是在所有实体上实现包装属性,这些实体私下存储任何属性更改,而不影响实际的实体属性。然后,我将向实体添加一个SaveChanges()方法,该实体会将更改写入实体,然后在上下文中调用SaveChanges()。

这种方法的问题是您需要使所有实体符合此模式。但是,它似乎工作得很好。它确实有另一个缺点,如果你做了很大的改动,以大量的对象有很多数据,你最终在内存中外来副本。

我能想到的唯一的其他解决方案是,在保存更改后,保存所有更改/添加/删除实体的实体状态,将它们设置为未修改,除了要更改的实体状态外,请保存更改,然后恢复其他实体的状态。但是这听起来可能很慢。

相关问题