简体   繁体   中英

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. 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. 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.

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.

Loading the navigation with .Include(banana => banana.Consumer) works, and so does loading it via 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.


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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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