EF4保存复杂的分离对象图

时间:2011-08-03 23:29:32

标签: entity-framework c#-4.0 entity-framework-4 entityobject

我有以下基于EntityObject的EF模型(这里写的属性作为保持代码清洁的字段):

Booking 
{
   int BookingID;
   EntityCollection<BookingCustomer> BookingCustomers;
   string Notes;
}

BookingCustomer 
{
   Customer Customer;
   Booking Booking;
   int CustomerID;
   int BookingID;
   string Notes;
}

Customer 
{
   int CustomerID;
   string Name;
}

我正在以分离的方式加载对象图:

Booking existingBooking;
using(MyContext ctx = new MyContext())
{
    ctx.Bookings.MergeOption = MergeOption.NoTracking;
    ctx.BookingCustomers.MergeOption = MergeOption.NoTracking;
    ctx.Customers.MergeOption = MergeOption.NoTracking;
    existingBooking = ctx.Bookings
       .Include("BookingCustomers")
       .Include("BookingCustomers.Customer")
       .First();
}

修改预订和客户数据:

existingBooking.Notes = "Modified";
existingBooking.BookingCustomers.First().Name += " Edited";

保存:

using(MyContext ctx = new MyContext())
{
        ctx.Bookings.Attach(existingBooking);
        ctx.ObjectStateManager.GetObjectStateEntry(existingBooking ).SetModified();
        ctx.Refresh(RefreshMode.ClientWins, existingBooking);    
        ctx.SaveChanges();
} 

我创建了客户记录(而不是更新现有记录)。

我也试过这个:

using(MyContext ctx = new MyContext())
{
    ctx.Customers.Attach(existingBooking.BookingCustomers.First());
    ctx.ObjectStateManager.GetObjectStateEntry(existingBooking.BookingCustomers.First()).SetModified();
    ctx.Refresh(RefreshMode.ClientWins, existingBooking.BookingCustomers.First());

    ctx.Bookings.Attach(existingBooking);
    ctx.ObjectStateManager.GetObjectStateEntry(existingBooking ).SetModified();
    ctx.Refresh(RefreshMode.ClientWins, existingBooking);    
    ctx.SaveChanges();
} 

但在第ctx.Customers.Attach(existingBooking.BookingCustomers.First());行获取例外:

System.InvalidOperationException: A referential integrity constraint violation occurred: The property values that define the referential constraints are not consistent between principal and dependent objects in the relationship.

我怎样才能让它发挥作用?

2 个答案:

答案 0 :(得分:1)

不是关于提神。如果您在分离状态下修改图形,则EF无法找到您所做的更改。您必须手动设置每个modified entity or relation的状态。 Attach会将整个图表放在Unchanged状态,而ChangeObjectState只会影响图表中的单个实体。

您发现最简单的方法是在保存期间再次加载整个图形并手动将更改合并到附加图形。特别是如果你想删除一些关系/实体或者做多对多关系的复杂操作,这将是很方便的。

答案 1 :(得分:1)

Ladislav是对的。但是,还有一个选项可以考虑哪个可以解决这个问题,并且仍然允许您保留已分离的模型 - 自我跟踪POCO。有一个T4模板(它与VS2010捆绑在一起或可以下载),它允许对象图跟踪其状态(这包括在图中添加/删除对象以及对象的属性已更改)以便您可以重新附加已经修改过的图表; EF4将找出更改并将其应用于对象状态管理器。