简体   繁体   English

.Net核心实体框架 - Discrimator TPH

[英].Net Core Entity Framework - Discrimator TPH

I'm currently trying to write to a table which inherits from an abstract base class. 我目前正在尝试写入一个继承自抽象基类的表。 When I try to do this I get the following error (The ContactMethod property is the discriminator): 当我尝试这样做时,我得到以下错误(ContactMethod属性是鉴别器):

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

EmailContactDetails.cs: 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: 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: 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 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();
    }
}

I've tried hiding the discriminator "ContactMethod" by adding the following to the ContactDetailConfiguration.cs file: 我已经尝试通过将以下内容添加到ContactDetailConfiguration.cs文件来隐藏鉴别器“ContactMethod”:

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

Once I've done that I end up with the following error 一旦我这样做,我最终得到以下错误

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

You shouldn't hide the property configured as TPH discriminator from EF because it is essential for EF Core implementation of the TPH strategy. 您不应该将配置为TPH鉴别器的属性隐藏在EF中,因为它对于EF Core策略的EF Core实施至关重要。

The initial error simply indicates that your model and database are out of sync. 初始错误只表示您的模型和数据库不同步。 It's true that by convention EF Core uses string shadow property and column called Discriminator . 按惯例,EF Core使用string 阴影属性和名为Discriminator列。 But the whole purpose of HasDiscriminator fluent API is to allow changing the discriminator property/column type, as well as mapping it to an existing property of your entity model. HasDiscriminator流畅API的全部目的是允许更改鉴别器属性/列类型,以及将其映射到实体模型的现有属性。

Which is the case here. 这是哪种情况。 You've told EF Core to use your existing property ContactMethod as discriminator, hence EF Core is looking for column named ContactMethod in the database table. 您已经告诉EF Core使用您现有的属性ContactMethod作为鉴别器,因此EF Core正在数据库表中查找名为ContactMethod的列。 So to resolve the issue, simply update your database from the model (using the usual procedure when model is changed - add new migration, update database etc). 因此,要解决此问题,只需从模型更新数据库(使用模型更改时的常规过程 - 添加新迁移,更新数据库等)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM