2010-05-28 36 views
6

我使用EF 4,使用sprocs为我的实体映射所有CUD操作。Entity Framework 4 EntityState未更改的实体更新

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

这里是我运行代码:

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

更新与我retrieveing的人相关的地址 - 尽管他们没有在代码中的任何方式明确地联系在一起。当context.SaveChanges()执行时,不仅我的Address实体的Update sproc被激发(就像您所期望的那样),但Person实体的Update sproc也是如此 - 即使您可以看到没有对该实体做出任何更改人员实体。

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

为什么更新sproc被调用Person实体?有没有可以设置的某种设置来防止这种情况发生?


我创建了一个第二个项目,以确保该问题是不是因为在我的当前项目环境出事。

首先,我创建了一个包含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(); 
    } 
    } 

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

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

做完映射后,我运行了程序。因此,我观察到看到更新OrderDetail表的预期行为,但此外Order表“更新后”触发器已被触发,并且UdateDateTime字段被设置为更新发生的日期和时间 - 我不希望这样做。

有谁知道一种方法来利用所有插入,更新和删除操作的存储过程,并没有更新级联到相关的实体?

+0

只是为了确保没有其他代码与您的错误相关联? – Nix 2010-05-28 18:46:44

+0

我没有看到错误。我只是没有看到我期望的行为,我想知道为什么和我需要做什么才能看到预期的行为,即只有Address实体在数据库中得到更新。 唯一的其他代码将是我的上下文对象的实例化,它只是创建一个EF生成的实体上下文的新实例。 – Filosopher 2010-05-28 18:56:30

+0

更新:正如我在我原来的发布中所说的,我使用存储过程来处理所有我的表上的创建,更新和删除。我只是从我的Model中删除这些映射,然后在Person表上使用DB触发器再次运行代码,并且没有发生更新。看起来像是创建,更新和删除的sproc映射,导致更新发生在这种情况下。不幸的是,我们不得不为这些操作使用sprocs,因此仍然需要解决方案。我只是想我会用更多的信息更新这篇文章。 – Filosopher 2010-05-28 20:11:34

回答

4

我有这个相同的问题,并已通过在that MS KBD page上提到的修补程序解决。

该修复程序仅在.NET 4.5中广泛发布。不过,我期望EF 6(它可以在.NET 4/.NET 4.5上运行)也将提供该修补程序,因为它取代了自带.NET 4版本的System.Data.Entity.dll。

相关问题