WithOptionalDependent vs WithOptionalPrinciple – Definitive Answer?

我认为这可能有助于得到一个明确的答案何时使用WithOptionalDependent和何时使用WithOptionalPrincipal 。 这两个函数的帮助有点不清楚,我发现自己通过多个Stack Overflow的答案和其他网站上的答案结合的答案,以确信我已经有了正确的方向关系。

以下是MSDN关于WithOptionalDependent所说的内容:

将关系configuration为可选:在关系的另一侧没有导航属性可选。 被configuration的实体types将是依赖项,并且包含一个到委托人的外键。 关系所针对的实体types将是关系中的主体。

以下是关于WithOptionalPrincipal

将关系configuration为可选:在关系的另一侧没有导航属性可选。 被configuration的实体types将是关系中的主体。 关系所针对的实体types将是依赖关系,并且包含一个外键给主体。

“正在configuration的实体types”这一行总是让我困惑的部分(我假设其他人)。

在这个例子中:

 class MyEntityA { [Key] public int Id { get; set; } public int BId { get; set; } [ForeignKey("BId")] public MyEntityB B { get; set; } } class MyEntityB { [Key] public int Id { get; set; } } modelBuilder.Entity<MyEntityA>().HasOptional(a => aB).WithOptionalDependent(); 

是“正在configuration的实体types”是指MyEntityA还是MyEntityB ? 我认为这是前者。

如果这是正确的,什么时候使用WithOptionalPrincipal

我其实在我的代码示例中应该是WithMany而不是WithOptional选项。 显然我还是很困惑!

对于这两个导航属性朝向另一个方向的函数,都有重载。 我认为这些超载不会改变这些答案,但如果我错了,请纠正我。

我希望这对更大的社区也有帮助。

例如,让我们通过导航属性修改您的EntityB ,并使BId空(正如我们正在谈论可选关系)。

 class MyEntityA { [Key] public int Id { get; set; } public int? BId { get; set; } [ForeignKey("BId")] public virtual MyEntityB B { get; set; } } class MyEntityB { [Key] public int Id { get; set; } public virtual MyEntityA A { get; set; } } 

那么我们可以使用:

 modelBuilder.Entity<MyEntityB>().HasOptional(a => aA).WithOptionalPrincipal(); 

MyEntityAMyEntityAFK ,所以在你的configuration文件中你可以configurationMyEntityA并使用WithOptionalDependent。 但是你可以从MyEntityB side开始configuration,那么你需要WithOptionalPrincipal。

你的问题的答案是:“正在configuration的实体types”是MyEntityA

这可以通过查看文档来明确地看到

 OptionalNavigationPropertyConfiguration<TEntityType, TTargetEntityType> 

这是HasOptional返回的types,它说:

TTargetEntityType

关系所针对的实体types。

这为短语提供了更多的上下文:

正在configuration的实体types

关系所针对的实体types

所以,就你的情况而言,你从HasOptional回来了

 OptionalNavigationPropertyConfiguration<MyEntityA, MyEntityB> 

因此, WithOptionalDependent意味着MyEntityB将成为一个Principal,其可选的 Navigation属性指向MyEntityA (通过重载的lambda参数指定),而MyEntityA将是Dependent,并且包含一个外键和导航属性(如HasOptional的lambda参数)。 这是你模型中的场景。

相反, WithOptionalPrincipal表示MyEntityA将成为Principal和MyEntityB的依赖外键和导航属性。