简体   繁体   中英

EF Core 5 TPT - Inherited object with different ID name

Usually applications are structured with ID field just naming it as "ID" at the database. But in the application where I'm working doesn't follow this convention. I have two tables, that is normalized to be represented with inheritance. The main table is called "Entity", and its primary key is called "IdEntity". And the other table, that inherits from Entity is called "Source", and its primary key is called "IdSource", but it isn't identity, is a foreign key to Entity.IdEntity.

In the current application (webforms) it works fine, and I need to represent it on a new application with EF Core and .NET Core 5. If I list with _context.Entities.Find(id) it works fine, but the same is not applicable when i do _context.Sources.Find(id).

My classes are defined as:

Entity

public class Entity
{
    [Column("IdEntity"), Key]
    public int Id { get; set; }
}

Source

public class Source : Entity
{
    [Column("IdSource"), Key]
    public int Id { get; set; }
}

Note that I'm specifying explicitly the ID column in Source. But when I run the query on code, I'm getting the error: "Microsoft.Data.SqlClient.SqlException: 'Invalid column name 'IdEntity'.'"

I traced the execution with SQL Server Profiler, and realized that EF is creating the query simply ignoring the Column header IdSource from Source and inserting IdEntity , creating something like this:

select * -- All fields
from Entity t
inner join Source t0 on t.IdEntity = t0.IdEntity 
/* Note that it is inserting t0.IdEntity, but the alias for t0 is for Source, that there are no fields named IdEntity */

How can I explicitly tell to EF Core that the primary key is IdSource and not IdEntity for Source?

Edit: this new application is Database-first and it is mandatory. I'm trying to migrate from an existing application based on Webforms.

Try using fluent API to configure a model

So that you could do something like this code easily for each entity class:

    public class SourceEntityTypeConfiguration : IEntityTypeConfiguration<Source>
    {
        public void Configure(EntityTypeBuilder<Source> builder)
        {
            builder
                .Property(b => b.Id)
                .HasColumnName("IdSource");               
        }
    }

I'm not sure if this question is still relevant for you, but maybe this information will be helpful: https://github.com/dotnet/efcore/issues/19811 . Shortly speaking, TPT with different ID-column-names is not possible yet

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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