【问题标题】:EF Relationship (1 to 0..1) won't be removed不会删除 EF 关系(1 到 0..1)
【发布时间】:2016-08-08 12:07:52
【问题描述】:

我在实体框架 6.1.1 版中有一个 Code First 模型,基本上看起来像这样:

public class TinMan {
    public int Id { get; set; }
    public virtual Heart Heart { get; set; }
}

public class Heart {
    public int Id { get; set; }
}

这在像这样的实际数据库中表示,其中 Heart_Id 列由 EF 自动生成,这也创建了两个表之间的外键关系:

TinMen:                 Hearts:

Id    Heart_Id          Id
1     1                 1
2     3                 2
3     NULL              3

创建不存在的关系,或更改现有关系都可以正常工作:

using (MyDbContext dbContext = new MyDbContext()) {
    TinMan bill = dbContext.TinMen.FirstOrDefault(man => man.Id == 1);
    if (bill != null) bill.Heart = 2;
    TinMan bob = dbContext.TinMen.FirstOrDefault(man => man.Id == 3);
    if (bob != null) bob.Heart = 1;
    dbContext.SaveChanges();
}

现在我尝试删除一个关系:

using (MyDbContext dbContext = new MyDbContext()) {
    TinMan jebediah = dbContext.TinMen.FirstOrDefault(man => man.Id == 2);
    if (jebediah != null) jebediah.Heart = null;
    dbContext.SaveChanges();
}

在执行此操作后,ID==2 的 TinMan 仍然在数据库中有一个 Heart,即它在数据库中设置为 NULL

为什么?

【问题讨论】:

  • 这并没有解释为什么将导航属性设置为null 不起作用,但请注意,如果没有额外的配置,EF 将考虑one-to-many 关系从HeartTinMan .

标签: c# .net entity-framework entity-framework-6


【解决方案1】:

试试这个:

using (MyDbContext dbContext = new MyDbContext())
{
    TinMan jebediah = dbContext.TinMen.FirstOrDefault(man => man.Id == 2);
    context.Entry(jebediah).Reference(t => t.Heart).CurrentValue = null;
    dbContext.SaveChanges();
}

根据我的评论,这是另一种方法:

using (MyDbContext dbContext = new MyDbContext())
{
    TinMan jebediah = dbContext.TinMen.FirstOrDefault(man => man.Id == 2);
    context.Entry(jebediah).Reference(t => t.Heart).Load();
    jebediah.Heart = null;
    dbContext.SaveChanges();
}

无论如何,在这种情况下,具有显式外键属性(例如public int? HeartId { get; set; } 可能是有利的。使用外键属性,您可以在不预加载相关实体的情况下删除关系。例如:

using (MyDbContext dbContext = new MyDbContext())
{
    TinMan jebediah = dbContext.TinMen.FirstOrDefault(man => man.Id == 2);
    jebediah.HeartId = null;
    dbContext.SaveChanges();
}

【讨论】:

  • 这有点像我在您回答时正在调查的内容。我试过了,它奏效了。知道为什么将属性设置为 null 不起作用吗?
  • 当您从数据库加载TinMan 实体时,相关的Heart 尚未加载,因为启用了延迟加载。因此,当您将其设置为 null 时,就 EF 而言,并没有真正发生任何事情。将相关的Heart 设置为null 将起作用如果它是预先加载的。我更新了我的答案(包括一个例子)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-06
  • 2021-11-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多