简体   繁体   English

Entity Framework Core - 无法删除可选的可为空关系

[英]Entity Framework Core - Cannot remove optional nullable relationship

Using Microsoft.EntityFrameworkCore version 5.0.7 and Npgsql.EntityFrameworkCore.PostgreSQL version 5.0.7 , I'm currently stuck trying to remove a relationship and have that change stored.使用Microsoft.EntityFrameworkCore版本5.0.7Npgsql.EntityFrameworkCore.PostgreSQL版本5.0.7 ,我目前一直在尝试删除关系并存储该更改。 Assume two models:假设两个模型:

public class Banana {
  public int Id { get; set; }
  public Consumer? Consumer { get; set; }
}
public class Consumer {
  public int Id { get; set; }
}

I'm able to assign a consumer just fine using我可以很好地分配一个消费者使用

myBanana.Consumer = dbContext.Consumers.First(row => row.Id == 1);
dbContext.Update(myBanana);
dbContext.SaveChanges();

and that works just fine - the database is updated accordingly.这工作得很好 - 数据库会相应地更新。 However, once that is stored, trying to remove the reference again using但是,一旦存储,尝试再次使用删除引用

myBanana.Consumer = null;
dbContext.Update(myBanana);
dbContext.SaveChanges();

fails.失败。 After saving, the old value is still in the database, not null as I would expect.保存后,旧值仍在数据库中,不像我期望的那样为null Interestingly, other changes to the banana are saved just fine.有趣的是,香蕉的其他更改保存得很好。

I'm not sure if I'm hitting a weird issue with Nullables, or if I'm just missing something, so I'd appreciate some hints.我不确定我是否遇到了 Nullables 的奇怪问题,或者我是否只是遗漏了一些东西,所以我希望得到一些提示。

If you want to continue using auto-generated foreign key properties , you have to make sure that the navigations are loaded.如果您想继续使用自动生成的外键属性,您必须确保导航已加载。 If they are lazy-loaded by default and you don't manually load them, the property will already be null before you try to assign null , so EF can't observe a change.如果他们是懒加载默认情况下,你不手动加载它们,物业就已经是null尝试分配之前null ,那么EF无法观察到的变化。

Loading the navigation with .Include(banana => banana.Consumer) works, and so does loading it via dbContext.Entry(myBanana).Reference(banana => banana.Consumer).Load() .使用.Include(banana => banana.Consumer)加载导航有效,通过dbContext.Entry(myBanana).Reference(banana => banana.Consumer).Load()加载导航也是如此。 After the relevant navigation items are loaded, myBanana.Consumer = null from the example in the question works as expected.加载相关导航项后,问题示例中的myBanana.Consumer = null将按预期工作。


If you have a non-tracking entity to work with (for example because it was generated by Model Binding), you can either get a tracking entity, or change the value of the auto-generated foreign key shadow property directly:如果您有一个非跟踪实体要使用(例如因为它是由模型绑定生成的),您可以获取一个跟踪实体,或者直接更改自动生成的外键影子属性的值:

dbContext.Entry(myBanana).Property("ConsumerId").CurrentValue = null;

which also works.这也有效。 This may be a little bit less polished since you depend on a string as the field name to be correct, but it can be a valid option depending on the circumstances.这可能不太完善,因为您依赖字符串作为正确的字段名称,但根据情况,它可能是一个有效的选项。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM