我已经得到了以下基于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将找出更改并为您将这些更改应用于对象状态管理器。