【问题标题】:EF4 save complex detached object graphEF4 保存复杂的分离对象图
【发布时间】:2011-10-19 13:22:32
【问题描述】:

我有以下基于 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.

我怎样才能让它工作?

【问题讨论】:

  • 你最终做了什么来解决这个问题?
  • 我最终使用了附加对象,以便从加载到保存都保持上下文。

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


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 我已经尝试了自我跟踪 POCO,实际上得到了相同的结果 - 每次我保存预订时都会创建新客户。
    • 有些不对劲。您可以在将对象附加到对象上下文之前查看对象的状态吗?它应该被标记为已修改。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多