Entity Framework 4实体,EntityState为Unchanged触发更新

时间:2010-05-28 18:39:54

标签: entity-framework

我正在使用EF 4,使用sprocs映射我的实体的所有CUD操作。

我有两张桌子,ADDRESS和PERSON。 PERSON可以有多个与之关联的ADDRESS。

以下是我正在运行的代码:

Person person = (from p in context.People
                             where p.PersonUID == 1
                             select p).FirstOrDefault();

Address address = (from a in context.Addresses
                               where a.AddressUID == 51
                               select a).FirstOrDefault();

address.AddressLn2 = "Test";

context.SaveChanges();

正在更新的地址与我正在检索的人员相关联 - 尽管他们没有在代码中以任何方式明确链接。当context.SaveChanges()执行时,我的地址实体的Update sproc不仅会被触发(就像你期望的那样),但是Person实体的Update sproc也是如此 - 即使你可以看到没有对人实体。

当我在context.SaveChanges()调用之前检查两个对象的EntityState时,我看到我的Address实体的EntityState为“Modified”,而我的Person enity的EntityState为“Unchanged”。

为什么要为Person实体调用Update sproc?是否有某种设置我可以设置以防止这种情况发生?


我创建了第二个项目,以确保问题没有发生,因为我当前的项目环境中存在某些问题。

首先,我创建了一个包含Order和OrderDetail表的新数据库。它们之间有一个外键,因此Order可以有多个与之关联的OrderDetail。我还在Order和OrderDetail表上创建了“更新后”数据库触发器,以便在更新记录时更新DateTime字段。

其次,我创建了一个简单的WPF应用程序,并创建了一个从我的数据库生成的ADO.NET实体模型。

第三,我将代码添加到我的类构造函数中,如下所示:

public partial class MainWindow : Window
  {
    public MainWindow()
    {
      InitializeComponent();

      MyEntities context = new MyEntities();

      Order order = (from o in context.Orders
              select o).FirstOrDefault();

      OrderDetail orderDetail = (from d in order.OrderDetails
                    select d).FirstOrDefault();

      orderDetail.Qty = 7;

      context.SaveChanges();
    }
  }

我在没有为Order和OrderDetail对象做任何函数映射的情况下运行程序。结果正是我期望看到的,OrderDetail记录更新为数量为7,UpdateDateTime字段填充更新发生的日期和时间。我的订单记录没有变化,这意味着没有更新。

然后我创建存储过程来处理DB中Order和OrderDetail表的更新。它们不做任何特殊操作,只接受表中每列的参数,然后将每个字段设置为等于相关参数。然后,我使用Mapping Details(Map Entity to Functions)窗口将这些存储过程映射到我的Model对象。

完成映射后,我运行了该程序。结果,我观察到了看到OrderDetail表更新的预期行为,但另外Order表“更新后”触发器已经触发,UdateDateTime字段被设置为更新发生的日期和时间 - 这是我不希望的。

是否有人知道如何利用存储过程进行所有插入,更新和删除操作,而不是将更新级联到相关实体?

1 个答案:

答案 0 :(得分:4)

我遇到了同样的问题,它已通过that MS KBD page中提到的修补程序解决了。

该修补程序仅在.NET 4.5中广泛发布。但是,我希望EF 6(适用于.NET 4 / .NET 4.5)也将提供该修复程序,因为它取代了随.NET 4一起提供的System.Data.Entity.dll版本。