如何使用 Fluent API 映射这种冗余的父子关系

Posted

技术标签:

【中文标题】如何使用 Fluent API 映射这种冗余的父子关系【英文标题】:How do I map this redundant parent-child relationship using Fluent API 【发布时间】:2015-07-27 10:49:01 【问题描述】:

关于如何双重映射这种父子关系的任何建议,其中父级具有正常的一对多关系(这是有效的),但是我需要从父级直接 1:1,0 链接到一个特定的孩子。

Public Class Source
    <Key()>
    Public Property SourceID As Int32

    Public Property SourceFields As List(Of SourceField)

    Public Property InboundMatchKeySourceFieldID As Nullable(Of Int32)
    Public Property InboundMatchKeySourceField As SourceField

Public Class SourceField
    <Key()>
    Public Property SourceFieldID As Int32

    Public Property SourceID As Int32

    Public Property Source As Source

这是父/子映射(工作)

    modelBuilder.Entity(Of Source).HasMany(
        Function(S) S.SourceFields
    ).WithRequired(
        Function(SF) SF.Source
    ).HasForeignKey(
        Function(SF) SF.SourceID
    )

这是我尝试额外的直接映射失败(不工作):

modelBuilder.Entity(Of Source
    ).HasOptional(
        Function(S) S.InboundMatchKeySourceField
    ).WithRequired(
        Function(SF) SF.Source
    )

这会产生“MetaDataException”:

指定的架构无效。错误:关系 '_____.Source_InboundMatchKeySourceField' 未加载 因为类型 '_____.SourceField' 不可用。

【问题讨论】:

【参考方案1】:

.WithRequired(...) 返回ForeignKeyNavigationPropertyConfiguration 的实例。您需要使用 map 方法将此关系映射到 Key,否则 EF 会尝试为您创建一个。

所以你要找的代码是:

modelBuilder.Entity(Of Source
).HasOptional(
    Function(S) S.InboundMatchKeySourceField
).WithRequired(
    Function(SF) SF.Source
) _
.Map(Function (x) x.MapKey("InboundMatchKeySourceFieldID"))

【讨论】:

好建议,唉,我仍然收到同样的错误信息【参考方案2】:

您不能对两种关系使用相同的属性SourceField.Source

从实体框架的角度来看存在歧义:

如果您设置someSourceField.Source,这是否意味着someSourceField 被添加到thatSource.SourceFields,或thatSource.InboundMatchKeySourceField 被设置,或两者兼而有之? 如果someSource.InboundMatchKeySourceField.Source != someSource怎么办?

也许您可以在没有导航属性的情况下创建第二个映射,并在需要时使用验证来确保 SourceFields.Contains(InboundMatchKeySourceField)thisSource.InboundMatchKeySourceField.Source == thisSource

modelBuilder.Entity(Of Source
    ).HasOptional(
        Function(S) S.InboundMatchKeySourceField
    ).WithRequired()

【讨论】:

以上是关于如何使用 Fluent API 映射这种冗余的父子关系的主要内容,如果未能解决你的问题,请参考以下文章

译第24节---Fluent API - 属性映射

如何在 Fluent NHibernate 中将一对一关系映射为复合键的一部分

使用自动映射时如何使用 Fluent NHibernate Validator?

Code First约定-Fluent API配置

EF Fluent API上

使用实体框架 Fluent Api 映射 System.Uri