Как определить модель предметной области, в которой первичный ключ также является внешним ключом с текущими API - PullRequest
0 голосов
/ 03 мая 2018

Моя проблема похожа на Возможно ли иметь отношение, где внешний ключ также является первичным ключом? , но я должен сделать это с 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'.

Ответы [ 2 ]

0 голосов
/ 03 мая 2018

То, что вы спрашиваете, это так называемые Связи общих первичных ключей , которые являются стандартной (и лучше поддерживаемой) моделью 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

Точно так же, как пример для Настройка обязательного-необязательного отношения (один-к-нулю или одному) из документации.

0 голосов
/ 03 мая 2018

Я бы попробовал что-то вроде этого:

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"));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...