首页 > 解决方案 > 如何使用流利的api定义主键也是外键的域模型

问题描述

我的问题类似于是否可能存在外键也是主键的关系?但我必须使用 Fluent API 来做到这一点。

我的情况与问题中描述的基本相同,但由于我们的编码标准,我不能在我的域模型上使用注释。这是一些代码(澄清):

领域类:

public class Table1
{
    public long ID { get; set; }
    public int SubTableType { get; set; }
    ...

    public Table2 Table2 { get; set; }
    public Table3 Table3 { get; set; }
    public List<Table4> Table4s { get; set; }
    public List<Table5> Table5s { get; set; }
}

public class Table2
{
    public long ID { get; set; }
    public string Location { get; set; }
    public string Task { get; set; }
    ...

    public Table1 Table1 { get; set; }
    public Table6 Table6 { get; set; }
    public List<Table7> Table7s { get; set; }
}

public class Table3
{
    public long ID { get; set; }
    public string DescriptionAndLocation { get; set; }
    ...

    public Table1 Table1 { get; set; }
}

配置类:

internal class Table1Configuration : EntityTypeConfiguration<Table1>
{
    public Table1Configuration()
    {
        ToTable("Table1");

        HasKey(so => so.ID);

        Property(so => so.SubTableType)
            .IsRequired();
        Property(so => so.ID)
            .IsRequired()
            .HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity);
        ...
    }
}

internal class Table2Configuration : EntityTypeConfiguration<Table2>
{
    public Table2Configuration()
    {
        ToTable("Table2");

        HasKey(bc => bc.ID);

        Property(bc => bc.ID)
            .IsRequired();
        Property(bc => bc.Location)
            .IsOptional()
            .HasColumnType("nvarchar")
            .HasMaxLength(50);
        Property(bc => bc.Task)
            .IsOptional()
            .HasColumnType("nvarchar")
            .HasMaxLength(4000);
        ...

        HasRequired(bc => bc.Table1)
            .WithOptional(so => so.Table2);
        HasRequired(bc => bc.Table8)
            .WithMany(bot => bot.Table2s)
            .HasForeignKey(bc => bc.Tabe8ID);
    }
}

internal class Table3Configuration : EntityTypeConfiguration<Table3>
{
    public Table3Configuration()
    {
        ToTable("Table3");

        HasKey(hic => hic.ID);

        Property(hic => hic.DescriptionAndLocation)
            .IsOptional()
            .HasColumnType("nvarchar")
            .HasMaxLength(4000);
        Property(hic => hic.ID)
            .IsRequired()
            .HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity);

        HasRequired(hic => hic.Table1)
            .WithOptional(so => so.Table3);
    }
}

当我运行此代码时,我收到错误:

Invalid column name 'Table2_ID'.

标签: c#sql-serverentity-frameworkef-fluent-api

解决方案


您要问的是所谓的Shared Primary Key Associations,它是一对一关系的标准(并且得到更好的支持)EF6 模型。

ID您应该删除MapKey用于定义影子 FK 属性(您不需要)的调用,而不是删除该属性。

ID由于按惯例调用的属性是 PK 并且是必需的,因此您基本上只需要这样:

HasRequired(hic => hic.Table1)
    .WithOptional(so => so.Table2); // or Table3

[Key]或/[ForeignKey]组合的显式等价物:

HasKey(hic => hic.ID);

HasRequired(hic => hic.Table1)
    .WithOptional(so => so.Table2); // or Table3

与文档中配置必需到可选关系(一对零或一)的示例完全相同。


推荐阅读