如何在两个实体之间配置一对一关系,其中一个是主体?

时间:2013-10-25 17:24:01

标签: c# entity-framework

我正在使用Entity Framework和流畅的API来配置绑定。我的两个实体看起来像这样:

public class Matter
{
    #region Properties

    /// <summary>
    /// Primary key
    /// </summary>
    public int Id { get; set; }

    /// <summary>
    /// Navigation: the most recent Relativity activity for the Matter
    /// </summary>
    public virtual RelativityActivity RelativityRecentActivity { get; set; }

    #endregion
}

public class RelativityActivity
{
    #region Properties

    /// <summary>
    /// Primary key
    /// </summary>
    public int Id { get; set; }

    /// <summary>
    /// Foreign key: the Matter that the Relativity Activity entry is associated with
    /// </summary>
    public Matter Matter { get; set; }

    #endregion
}

我正在使用现有的表架构,并且在架构中RelativityActivity表只有Matter的{​​{1}}列的外键。因此,Id是关系中的主体,可以在没有Matter的情况下存在。但是,如果没有RelativityActivity,则RelativityActivity不能存在。

对于我的生活,我似乎无法按照我的预期将其配置为工作。我已经阅读了很多关于SO的答案,并且在阅读每一个后我调整了我的流畅的API绑定,但我似乎总是得到错误,范围从“不能确定关系的主要结束”到“你用不正确的多重性配置它”

我目前流畅的API绑定如下所示:

Matter

代表modelBuilder.Entity<RelativityActivity>().HasRequired(m => m.Matter).WithRequiredDependent(m => m.RelativityRecentActivity).Map(m => m.MapKey("matter")).WillCascadeOnDelete(true); ,并且:

RelativityActivity

代表modelBuilder.Entity<Matter>().HasOptional(m => m.RelativityRecentActivity).WithRequired(m => m.Matter);

我在关系中有两个绑定,因为没有Matter绑定我无法确定主要结束错误。但是现在我得到了关于多重性的错误。

编辑以澄清:

Matter表中的外键列不是RelativityActivity列。它实际上是另一个名为Id的列。我尝试使用绑定中的matter函数来指定它。

1 个答案:

答案 0 :(得分:1)

db模式只能强制执行0..1 - n关联。 1:1关联始终涉及两个相互引用的外键,或者同时是另一个主键的外键的主键。

您可以按照以下方式建立1:1关联模型:

modelBuilder.Entity<Matter>().HasOptional(m => m.RelativityRecentActivity)
                             .WithRequired(m => m.Matter);

问题是EF会假设数据库架构也适应1:1关联。

如果要保存MatterRelativityRecentActivity对象,EF会插入Matter记录并将其PK值用作RelativityRecentActivity的PK (假设它也是FK)。因此,在您的情况下,真正的外键字段永远不会被填充。除此之外,如果RelativityRecentActivity具有自动递增PK(Sql Server中的标识列),它也可能引发异常。

因此,我认为您只能将关联建模为常规的1-many关联,并使用业务规则来强制执行“many”永远不会超过1:

modelBuilder.Entity<Matter>().HasMany(m => m.RelativityRecentActivity)
            .WithRequired(r => r.Matter)
            .Map(m => m.MapKey("matter");