.Net Core Entity Framework - Дискриматор TPH

В настоящее время я пытаюсь записать в таблицу, которая наследуется от абстрактного базового класса. Когда я пытаюсь сделать это, я получаю следующую ошибку (свойство ContactMethod является дискриминатором):

System.Data.SqlClient.SqlException: Invalid column name 'ContactMethod'.

EmailContactDetails.cs:

public class EmailContactDetail : ContactDetail
{
    [ApiMember(Description = "The Contact Method")]
    public override ContactMethod ContactMethod => ContactMethod.Email;

    [ApiMember(Description = "Email Address")]
    public string EmailAddress { get; set; }
}

EmailContactDetailConfiguration.cs:

public class EmailContactDetailsConfiguration : IEntityTypeConfiguration<EmailContactDetail>
{
    public void Configure(EntityTypeBuilder<EmailContactDetail> builder) => Configure(builder, "dbo");

    public void Configure(EntityTypeBuilder<EmailContactDetail> builder, string schema)
    {
        builder.Property(x => x.EmailAddress).HasColumnName("EmailAddress").HasColumnType("nvarchar(255)");
    }
}

ContactDetail.cs:

public abstract class ContactDetail
{
    [ApiMember(Description = "The Identifier")]
    public Guid Id { get; set; }

    [ApiMember(Description = "The Contact Method")]
    public virtual ContactMethod ContactMethod { get; set; }
}

ContactDetailConfiguration.cs

public class ContactDetailsConfiguration : IEntityTypeConfiguration<ContactDetail>
{
    public void Configure(EntityTypeBuilder<ContactDetail> builder) => Configure(builder, "dbo");

    public void Configure(EntityTypeBuilder<ContactDetail> builder, string schema)
    {
        builder.ToTable("ContactDetails", schema);

        // Table per hierarchy. all subclasses share the same db table for performance.
        builder.HasDiscriminator(x => x.ContactMethod)
            .HasValue<EmailContactDetail>(ContactMethod.Email);

        builder.Property(x => x.Id).HasColumnName("Id").IsRequired().HasColumnType("uniqueidentifier").ValueGeneratedOnAdd();
    }
}

Я попытался скрыть дискриминатор "ContactMethod", добавив следующее в файл ContactDetailConfiguration.cs:

builder.Ignore(x => x.ContactMethod);

Как только я это сделаю, я получаю следующую ошибку

The entity type 'EmailContactDetail' is part of a hierarchy, but does not have a discriminator property configured.

1 ответ

Решение

Не следует скрывать свойство, настроенное как дискриминатор TPH, от EF, потому что это важно для реализации стратегии TPH в EF Core.

Первоначальная ошибка просто означает, что ваша модель и база данных не синхронизированы. Это правда, что по соглашению EF Core использует string теневое свойство и столбец с именем Discriminator, Но вся цель HasDiscriminator Свободный API позволяет изменять свойство дискриминатора / тип столбца, а также сопоставлять его с существующим свойством вашей модели сущности.

Какой случай здесь. Вы сказали EF Core использовать вашу существующую собственность ContactMethod как дискриминатор, поэтому EF Core ищет столбец с именем ContactMethod в таблице базы данных. Поэтому, чтобы решить проблему, просто обновите свою базу данных из модели (используя обычную процедуру при изменении модели - добавьте новую миграцию, обновите базу данных и т. Д.).

Другие вопросы по тегам