如何定义一个域模型,其中主键也是流利的外键 api

How to define a domain model where the Primary Key is also the Foreign Key with fluent 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'.

我会尝试这样的事情:

modelBuilder.Entity<Table1>().HasKey(t => t.ID);
modelBuilder.Entity<Table1>().Property(t =>t.ID)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

modelBuilder.Entity<Table1>()
            .HasOptional(t1 => t1.Table2)
            .WithRequired(t2 => t2.Table1).Map(m => m.MapKey("ID"));

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

与其删除 ID 属性,不如删除用于定义影子 FK 属性 的 MapKey 调用(您不需要).

由于约定俗成的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

与文档中 Configuring a Required-to-Optional Relationship (One-to–Zero-or-One) 的示例完全相同。