Description
openedon Jun 23, 2020
I'd like to model a type hierarchy using TPH inheritance where the same property exists on two derived entities and maps to the same underlying column in a SQL Server DB but has different nullability.
When I create my DbContext and model the entities, making sure I explicitly specify the column name, I end up getting a following exception at runtime:
System.InvalidOperationException : 'Derived1.Property' and 'Derived2.Property' are both mapped to column 'Property' in 'Base' but are configured with different nullability.
Steps to reproduce
Let's have entities Derived1
and Derived2
, both siblings in the type hierarchy with ancestor Base
and mapping to table Base
with backing column named Property
that allows NULL. In my scenario, the property Property
is required in Derived1
but optional in Derived2
. Therefore I don't model the property on Base
entity, but I add the property with the same name and type to Dervied1
and Derived2
. The code may look something like this:
class Base
{
}
class Derived1
{
string Property { get; set; }
}
class Derived2
{
string Property { get; set; }
}
class BaseMap : EntityTypeConfiguration<Base>
{
public override void Configure(EntityTypeBuilder<Base> builder)
{
base.Configure(builder);
builder.ToTable("Base");
builder.HasDiscriminator<string>("Discriminator")
.HasValue<Derived1>("Derived1")
.HasValue<Derived1>("Derived2");
}
}
class Derived1Map: IEntityTypeConfiguration<Derived1>
{
public void Configure(EntityTypeBuilder<Derived1> builder)
{
builder.HasBaseType<Base>();
builder.Property(e => e.Property).HasColumnName("Property").IsRequired(true);
}
}
class Derived2Map : IEntityTypeConfiguration<Derived2>
{
public void Configure(EntityTypeBuilder<Derived2> builder)
{
builder.HasBaseType<Base>();
builder.Property(e => e.Property).HasColumnName("Property").IsRequired(false);
}
}
I came across issue #17820 and its fix 218f92c where the check for different nullability was added. I opened this originally as discussion question 21366 where @AndriySvyryd kindly advised that I open and issue as this is a bug.
Just a thought - I suppose an extra complication would arise in case of nullable value types. In my case above, the property was of type string
/nvarchar
hence a reference type that allows nulls (we don't use nullable reference types). For example, when the property is datetime
in DB as that would need to be modeled as DateTime
in Derived1
(required) and DateTime? in Derived2
(optional).
Further technical details
EF Core version: 5.0.0-preview.5.20278.2 but should also be reproducible in 3.1
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: .NET 5 preview 5 but also .NET Core 3.1
Operating system: Windows 10 Enterprise build 18363
IDE: Visual Studio 2019 16.6.2