EF4保存复杂的分离对象图



我已经得到了以下基于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.

我怎样才能使它工作?

这不是关于刷新。如果您在分离状态下修改图形,EF将无法找到您所做的更改。必须手动设置每个已修改实体或关系的状态。Attach会使整个图处于Unchanged状态,而ChangeObjectState只影响图中的单个实体。

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

Ladislav说得对。但是,您应该考虑另一个选项,它可以解决这个问题,并且仍然允许您保留分离的模型-自跟踪poco。有一个T4模板(它要么与VS2010捆绑在一起,要么作为下载可用),它允许对象图跟踪其状态(这包括添加/删除对象到图中,以及对象的属性发生了变化),以便您可以重新连接已进行修改的图;EF4将找出更改并为您将这些更改应用于对象状态管理器。

最新更新