实体框架4实体状态保持不变的触发更新 [英] Entity Framework 4 Entity with EntityState of Unchanged firing update

查看:78
本文介绍了实体框架4实体状态保持不变的触发更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用EF 4,使用存储过程为我的实体映射所有CUD操作。



我有两个表,ADDRESS和PERSON。一个人可以有多个与之关联的地址。



这是我正在运行的代码:

  Person person =(从上下文中的p.People 
其中p.PersonUID == 1
选择p).FirstOrDefault();

地址地址=(从上下文中的地址。地址
其中a.AddressUID == 51
选择a).FirstOrDefault();

address.AddressLn2 =测试;

context.SaveChanges();

正在更新的地址与我正在检索的人相关联-尽管它们在任何情况下均未明确链接代码中的方式。当context.SaveChanges()执行时,不仅会激发我的Address实体的Update sproc(就像您期望的那样),而且Person实体的Update sproc也不会被触发-即使您可以看到对人实体。



当我在context.SaveChanges()调用之前检查两个对象的EntityState时,我看到我的Address实体的EntityState为 Modified,而我的Person实体有一个EntityState为未更改。



为什么要为Person实体调用Update proc?我可以设置某种设置来防止这种情况发生吗?






我创建了第二个项目确保由于我当前的项目环境中的某些问题而没有发生此问题。



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



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



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

 公共局部类MainWindow:窗口
{
public MainWindow()
{
InitializeComponent();

MyEntities上下文= new MyEntities();

订单订单=(从上下文中的o开始。订单
选择o).FirstOrDefault();

OrderDetail orderDetail =(从d中订购.OrderDetails
选择d).FirstOrDefault();

orderDetail.Qty = 7;

context.SaveChanges();
}
}

我运行程序时没有为我做任何功能映射Order和OrderDetail对象。结果恰好是我期望看到的结果,OrderDetail记录被更新为Qty为7,并且UpdateDateTime字段填充了发生更新的日期和时间。我的Order记录没有更改,这意味着没有更新。



然后,我创建存储过程来处理DB中Order和OrderDetail表的更新。他们没有做任何特别的事情,只接受表中每一列的参数,然后将每个字段设置为与关联的参数相等。然后,我使用映射详细信息(将实体映射到功能)窗口将这些存储过程映射到我的Model对象。



完成映射后,我运行了程序。结果,我观察到看到对OrderDetail表进行更新的预期行为,但是此外,激发了Order表更新后触发器,并将UdateDateTime字段设置为发生更新的日期和时间-这是我所不希望的。



有人知道一种利用存储过程执行所有插入,更新和删除操作的方法,而没有将更新级联到相关实体吗?

解决方案

我遇到了同样的问题,并且该MS KBD页面



该修补程序仅在.NET 4.5中广泛发布。但是,我希望EF 6(在.NET 4 / .NET 4.5上都可以使用)也将提供该修复程序,因为它会取代.NET 4附带的System.Data.Entity.dll版本。

I am using EF 4, mapping all CUD operations for my entities using sprocs.

I have two tables, ADDRESS and PERSON. A PERSON can have multiple ADDRESS associated with them.

Here is the code I am running:

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();

The Address being updated is associated with the Person I am retrieveing - although they are not explicitly linked in any way in the code. When the context.SaveChanges() executes not only does the Update sproc for my Address entity get fired (like you would expect), but so does the Update sproc for the Person entity - even though you can see there was no change made to the Person entity.

When I check the EntityState of both objects before the context.SaveChanges() call I see that my Address entity has an EntityState of "Modified" and my Person enity has an EntityState of "Unchanged".

Why is the Update sproc being called for the Person entity? Is there a setting of some sort that I can set to prevent this from happening?


I created a second project to make sure the issue was not happening because of something in my current project environment.

First, I created a new database that contains an Order and OrderDetail table. They have a foreign key between them so that Order can have more than one OrderDetail associated with it. I also created "after Update" DB triggers on the Order and OrderDetail tables that update a DateTime field when a record is updated.

Second, I created a simple WPF application and created a ADO.NET Entity Model that was generated from my database.

Third, I added code to my class constructor as follows:

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();
    }
  }

I ran the program without doing any function mapping for my Order and OrderDetail objects. The result was exactly what I would expect to see, the OrderDetail record is updated to have a Qty of 7 and the UpdateDateTime field is populated with the date and time the update occurred. No changes to my the Order record which means no update occurred.

I then create stored procedures to handle the update of Order and OrderDetail tables in the DB. They don't do anything special, just accept parameters for every column in the table and then set each field equal to the associated parameter. I then mapped those stored procedures to my Model objects using the Mapping Details (Map Entity to Functions) window.

After doing the mapping, I ran the program. As a result I observed the expected behavior of seeing updates to the OrderDetail table, but in addition the Order table "after Update" trigger had fired and the UdateDateTime field was set to the date and time the update occurred - which I would not expect.

Does anyone know of a way to utilize stored procedures for all Insert, Update and Delete operations and not have the updates cascade up to related entities?

解决方案

I had this same issue, and it has been solved by the hotfix mentioned on that MS KBD page.

The fix was only published widely in .NET 4.5. However, I expect that EF 6 (which works both on .NET 4 / .NET 4.5) will also ship that fix, as it supersedes the version of System.Data.Entity.dll shipped with .NET 4 with its own.

这篇关于实体框架4实体状态保持不变的触发更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆