dotnet / efcore

EF Core is a modern object-database mapper for .NET. It supports LINQ queries, change tracking, updates, and schema migrations.
https://docs.microsoft.com/ef/
MIT License
13.68k stars 3.17k forks source link

Improve the exception message for when the discriminator property was ignored #34404

Open voroninp opened 1 month ago

voroninp commented 1 month ago

Here's how I map entities:

public abstract class Foo
{
    public int Id { get; private set; }
    public abstract int FooType { get; }
}

public sealed class Bar1 : Foo
{
    public override int FooType => 1;
}

public sealed class Bar2 : Foo
{
    public override int FooType => 2;
}

public sealed class Context : DbContext
{
    private readonly string _connectionString;

    public Context(string connectionString)
    {
        _connectionString = connectionString;
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseNpgsql(_connectionString);
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Foo>(e =>
        {
            e.HasDiscriminator<int>("FooType")
            .HasValue<Bar1>(1)
            .HasValue<Bar2>(2);

            e.Ignore(p => p.FooType);
        });

        modelBuilder.Entity<Bar1>();
        modelBuilder.Entity<Bar2>();
    }
}

When I run context.Database.EnsureCreatedAsync() I get InvalidOperationException:

'Both 'Bar1' and 'Foo' are mapped to the table 'Foo'. All the entity types in a non-TPH hierarchy (one that doesn't have a discriminator) must be mapped to different tables. See https://go.microsoft.com/fwlink/?linkid=2130430 for more information.'

As soon as I change the name of discriminator, everything works fine. If discriminator cannot be named as ignored property this should be in the docs and error message should be more helpful. Here is the repo to reproduce the problem.

Include provider and version information

EF Core version: 8.0.4 Database provider: PostgreSQL Target framework: .NET 8

ajcvickers commented 1 month ago

@voroninp Ignoring a CLR property with a given name and replacing it with a shadow property of the same name is not supported. In other words, a shadow property can only use a name that is not that of a CLR property.

voroninp commented 1 month ago

That was my guess, that this is a limitation. But the error message could be frinedlier in this case ;-)