【问题标题】:How to properly Delete fields of an Entity?如何正确删除实体的字段?
【发布时间】:2015-07-01 19:51:12
【问题描述】:

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

假设我有两个实体:PersonWork。 我可以毫无问题地改变一个人的工作,但是当我试图表达这个人失业时,它就不能正常工作:

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

运行此代码后,该人仍然会有以前的工作,但如果我使用调试器并在运行前检查 personWork 属性 person.Work = null;,一切都会按预期运行。

谁能解释一下为什么先读取值会使代码正常工作以及如何正确删除该字段?

 var work = person.Work; \\ with this line here everything works as expected
 person.Work = null;
 db.SaveChanges();

【问题讨论】:

  • 我会说这不是完全相同的问题,但stackoverflow.com/questions/22557699/… 的回答肯定会有所帮助。我现在正在做db.Entry(person).Reference(x => x.Work ).CurrentValue = null;,这就像一个魅力。
  • 请参阅下面的答案。您的问题是 EF 无法识别您已更改此人的 Work 属性。通常(总是)是因为 EF 无法为 person 构建代理,因为您没有将属性 Work 标记为 virtual。

标签: entity-framework entity-framework-6


【解决方案1】:

导致您的问题的两件事:

  1. 实体框架通过tracking changes 确定在SaveChanges 期间需要将哪些内容更新为属性值。
  2. 您可能启用了lazy loading(一般情况下和Work 属性),这意味着如果person 具有关联的Work,则该关联实体直到第一次加载您访问该属性。

将它们放在一起,当您设置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;

【讨论】:

  • 不使用外键属性有可能解决吗?
  • 属性设置为person.Work = null之前不为空。我希望实体框架能够在不需要外键属性的情况下检测到更改。是否可以将实体标记为已修改或其他?
  • @kamayd:很抱歉空部分解释得不好——octavioccl 的编辑答案有更好的解释。本质上,导航属性需要先加载。让我也编辑一下。
  • @kamayd:至于另一种解决方案,请参阅 octavioccl 的回答
【解决方案2】:

来自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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-20
    • 1970-01-01
    • 2019-08-08
    • 1970-01-01
    相关资源
    最近更新 更多