EF 插入具有导航属性的 属性,同时递归地忽略导航属性

EF Insert a property with navigation properties, while ignoring the navigation properties recursively

我正在使用 .Net6 核心,采用 EF 代码优先方法。

我有 类 个赞

class Foo {
   [Required]
   private Bar Bar {get; set;}; 
   ...
}

class Bar {
   [Required]
   private BarChild BarChild {get; set;}; 
   ...
}

class BarChild {
   ...
}

现在我想在数据库中插入一个 Foo 的实例,如下所示:

Context.Comments.Add(foo); 
Context.SaveChanges();

现在这给了我错误 'unique constraint failed ...' 因为 Foo 有一个导航 属性 到 BarBar 已经存在于数据库中。

我找到了解决方法:

Context.Entry(foo.Bar).State = EntityState.Unchanged;
Context.Entry(foo.Bar.BarChild).State = EntityState.Unchanged;

请注意,我还必须将 BarChild 的状态设置为未更改,即使我已经为 Bar 设置了状态。

问题是一些 类 有相当多的导航属性,它们本身也有导航属性,因此我的问题是,有没有更好的方法来 'ignore' 这些导航属性?

我不能只将它们设置为 null,因为在数据库中有一个引用这些导航属性的外键。

对于不涉及欺骗更改跟踪器认为它已经看到实际上是新 Bar 的其他选项,如果您在 Foo 中有 Bar 的 ID 属性,则可以改为设置它并且EF 将编写一个与现有 Bar 相关的 Foo 而不会尝试编写一个 Bar

class Foo {
   int BarId {get; set;}
   Bar Bar {get; set;}; 
   ...
}

如果您知道数据库包含 Bar 3 并且您希望新的 Foo's Bar 成为那个 Bar,您可以:

db.Foos.Add(new Foo { BarId = 3, ... });
db.Save...

您也可以下载已有的栏:

var f = new Foo { Bar = db.Bars.Find(3) };
db.Foos.Add(f);
db.Save...

..这可能不太受欢迎,因为它有点浪费资源,除非你需要检索 Bar 来对它做其他事情