EF Core 删除对自身的引用而不删除



我有一个类,它引用自己作为"等效版本"链;但是一旦设置,我就无法清除此引用。

public class Foo
{
public int FooId { get; set; }
public string Name { get; set; }
public virtual Foo EquivalentFoo { get; set; }
public static void RunFluent(ModelBuilder modelBuilder)
{
EntityTypeBuilder<Foo> entity = modelBuilder.Entity<Foo>();
entity.HasKey(f => f.FooId);
entity.HasOne(f => f.EquivalentFoo).WithMany().IsRequired(false);
}
}

我的控制器具有以下更新终结点:

[HttpPut("{id}")]
public async Task<IActionResult> PutFoo(int id, Foo foo)
{
...
_context.Entry(foo).State = EntityState.Modified;
if (foo.EquivalantFoo != null)
{
_context.Entry(foo.EquivalantFoo).State = EntityState.Unchanged;
}
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException ex)
{
...
}
return NoContent();
}

这可以很好地将新EquivalentFoo添加到没有新,或将其更改为新的 Foo。

我正在努力解决的是传递一个与EquivalentFoo = null的 foo .即使EquivalentFoo可为空,并且数据库可以使用空键,EF Core 生成的外键列也不会更新为显示 null。它甚至不会抛出错误,只是不更新。

请注意,在这种情况下,我实际上不想从数据库中删除任何这些 Foos。所有应该发生的是正在更新的 Foo 现在应该有一个引用任何EquivalentFoos的空键。

根据文档,将State设置为Modified应该将所有属性(包括阴影)也设置为修改。

但是,正如您已经观察到的那样,具有 null 值的影子 FK 属性(以及相应的参考导航属性同时为 null)似乎具有特殊处理,特别是未标记为由上述操作修改(如果您使用Update方法,则相同)。

因此,您需要强制 EF Core 更新 FK 属性,方法是使用Reference方法返回的ReferenceEntry手动将其标记为已修改,例如

//...
var entry = _context.Entry(foo);
entry.State = EntityState.Modified;
entry.Reference(e => e.EquivalentFoo).IsModified = true; // <--
//...

注意ParentFooRefno上的"?"标记,这将允许您添加空值

public class Foo
{
[Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int FooId { get; set; }
public string Name { get; set; }
public int? ParentFooRefno { get; set; }

[ForeignKey("ParentFooRefno ")]
public virtual Foo EquivalentFoo { get; set; }


}

最新更新