如何正确删除实体的字段?

时间:2015-07-01 19:51:12

标签: entity-framework entity-framework-6

尝试使用Entity Framework(版本6.1.3)删除实体的字段时遇到问题。

我们说我有两个实体:PersonWork。 我可以毫无问题地改变一个人的工作,但是当我试图表达该人失业时,它无法正常工作:

 person.Work = null;
 db.SaveChanges();

运行此代码之后,此人仍然可以使用以前的工作,但是如果我使用调试器并在运行之前检查Work的{​​{1}}属性 person,一切都会按预期运作。

有人可以解释为什么首先阅读该值会使代码正常工作以及如何正确删除该字段?

person.Work = null;

2 个答案:

答案 0 :(得分:1)

导致您的问题的两件事:

  1. 实体框架确定SaveChanges期间tracking changes对属性值需要更新的内容。
  2. 您可能已启用lazy loading(一般情况下都属于Work属性),这意味着如果person具有关联的Work,则该关联实体不会直到你第一次访问该属性时才开始加载。
  3. 将这些放在一起,当您设置person.Work = null而不访问person.Work(这将触发加载)时,上下文认为没有任何改变。但是如果您首先load属性,则将该属性设置为null会告知EF删除该关联。 编辑:根据the page octavioccl linked,这适用于.NET 4.0。但是对于.NET 4.5+(和EF 5+),首先不需要加载。

    可能的解决方案

    1. 如果要在不加载相关实体的情况下删除关联,则需要向Person实体添加外键属性,然后可以将其设置为null而不是设置导航属性为null。例如:

      public class Person
      {
          // other properties...
          public int? WorkId { get; set; }
          public virtual Work { get; set; }
      }
      
      person.WorkId = null;
      db.SaveChanges();
      
    2. octavioccl's answer引用了另一个选项:

        

      context.Entry(person).Reference(p => p.Work).CurrentValue = null;

答案 1 :(得分:0)

从此msdn page

  

要删除关系,请将导航属性设置为null。如果   您正在使用基于.NET 4.0的实体框架,   然后在将其设置为null之前需要加载相关的结尾。对于   例如:

context.Entry(person).Reference(p => p.Work).Load();
person.Work = null;
     

从基于.NET 4.5的Entity Framework 5.0开始   可以将关系设置为null而不加载相关的结尾。您   也可以使用以下方法将当前值设置为null

context.Entry(person).Reference(p => p.Work).CurrentValue = null;