dotnet / dotnet/efcore

Update docs: The property 'Kind' cannot be added to the type 'BaseEntity' because it is declared on the CLR type 'Child1Entity

Open
#36,928 2 comments 0 reactions 0 assignees View on GitHub
area-docs area-model-building customer-reported
Dominant language
C#
Stars
14.8k
Forks
3.4k
PR merge metrics
PR metrics pending

Description

## Update

I guess, this is by design. **There can be only one discriminator for the whole hierarchy, and the discriminator values should be provided for the leaves.**
This should be added to the documentation; currently nothing explicitly says that subhierarchy cannot have its own discriminator.
Also, EF should not silently switch to another discriminator column as it does now (see comments below).
Unfortunately, the error messages are confusing and misleading - they describe the issue with the underlying mapping, but do not account for the context of setting up the hierarchy.

### Bug description

When I use TPH mapping strategy, and define additional discriminator property on the child entity, I get this exception when trying to generate a migration.
If discriminator is defined using shadow property, it works fine.

See attached solution:
[NestedTPH.zip](https://github.com/user-attachments/files/22771677/NestedTPH.zip)

### Your code

```csharp
Here's the hierarchy:

abstract BaseEntity
abstract Child1Entity
concrete EntityA

The code of the classes:

public abstract class BaseEntity
{
public int Id { get; set; }
}

public abstract class Child1Entity : BaseEntity
{
public string Kind { get; private set; }
}

public sealed class EntityA : Child1Entity
{
}

The code for mapping which does not work:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity(entity =>
{
entity.HasKey(e => e.Id);
entity.Property(e => e.Id).ValueGeneratedOnAdd();

entity.HasDiscriminator("type")
.HasValue("Child 1");
});

modelBuilder.Entity(entity =>
{
entity.HasDiscriminator(e => e.Kind)
.HasValue("Entity A");
});
}

Yet this one works:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity(entity =>
{
entity.HasKey(e => e.Id);
entity.Property(e => e.Id).ValueGeneratedOnAdd();

entity.HasDiscriminator("type")
.HasValue("Child 1");
});

modelBuilder.Entity(entity =>
{
entity.HasDiscriminator("subtype")
.HasValue("Entity A");
});
}
```

### Stack traces

```text
Microsoft.EntityFrameworkCore.Design.OperationException: Unable to create a 'DbContext' of type 'AppDbContext'. The exception 'The property 'Kind' cannot be added to the type 'BaseEntity' because it is declared on the CLR type 'Child1Entity'.' was thrown while attempting to create an instance. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728
---> System.InvalidOperationException: The property 'Kind' cannot be added to the type 'BaseEntity' because it is declared on the CLR type 'Child1Entity'.
at Microsoft.EntityFrameworkCore.Metadata.Internal.TypeBase.AddProperty(String name, Type propertyType, MemberInfo memberInfo, Nullable`1 typeConfigurationSource, ConfigurationSource configurationSource)
at Microsoft.EntityFrameworkCore.Metadata.Internal.InternalTypeBaseBuilder.Property(Type propertyType, String propertyName, MemberInfo memberInfo, Nullable`1 typeConfigurationSource, Nullable`1 configurationSource, Boolean skipTypeCheck)
at Microsoft.EntityFrameworkCore.Metadata.Internal.InternalTypeBaseBuilder.Property(MemberInfo memberInfo, Nullable`1 configurationSource)
at Microsoft.EntityFrameworkCore.Metadata.Internal.InternalEntityTypeBuilder.HasDiscriminator(MemberInfo memberInfo, ConfigurationSource configurationSource)
```

### Verbose output

```text

```

### EF Core version

9.0.0

### Database provider

_No response_

### Target framework

_No response_

### Operating system

_No response_

### IDE

_No response_

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.