Reputation: 99
I try to implement a hierarchy in EF Core where I use the TPC strategy and have complex types in the abstract base class. I also use migrations, in Visual Studio Professional 2022.
My use-case is a natural fit for the TPC strategy in EF Core. Some properties should be present in all concrete classes, and are naturally grouped in distinct clusters. This is a good fit for complex types in the abstract base class, but the problem is that I'm not able to make it work. I get no complaints from the compiler when I declares and configures the complex types, but after generating the initial migration there is no sign of the complex types in the concrete types in the migration. What I do get is the simple types defined in the abstract base class and the complex types defined in each concrete class. I cannot find anything in the documentation that indicates that this is not possible. Have anybody had any success with using complex types with the TPC strategy, and if so, how was you able to make it work? I'm not an advanced user of EF Core, so if this is a trivial question I apologize in advance!
public abstract class AbstractBaseClass
{
public MyComplexType MyComplexProperty {get;set;}
}
public class ConcreteClass : AbstractBaseClass
{
public AnotherComplexType AnotherComplexProperty {get;set;}
}
public sealed class MyComplexType
{
public required string? PropertyOne {get;init;}
public required string? PropertyTwo {get;init;}
}
public sealed class AnotherComplexType
{
public required string? AnotherPropertyOne {get;init;}
public required string? AnotherPropertyTwo {get;init;}
}
public class ContextConfiguration
{
public void Configure(EntityTypeBuilder<AbstractBaseClass> builder)
{
builder.ComplexProperty(c => c.MyComplexProperty).IsRequired();
}
public void Configure(EntityTypeBuilder<ConcreteClass> builder)
{
builder.ComplexProperty(c => c.AnotherComplexProperty).IsRequired();
}
}
Upvotes: 0
Views: 309
Reputation: 89141
In TPC the abstract base class is not really an entity, so configuring the complex type on the base class won't work. Configure it on the concrete type or annotate the type with [ComplexType]
, eg
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<AbstractBaseClass>().UseTpcMappingStrategy();
modelBuilder.Entity<ConcreteClass>().ComplexProperty(c => c.AnotherComplexProperty).IsRequired();
modelBuilder.Entity<ConcreteClass>().ComplexProperty(c => c.MyComplexProperty).IsRequired();
}
or
[ComplexType]
public sealed class MyComplexType
{
public required string? PropertyOne { get; init; }
public required string? PropertyTwo { get; init; }
}
Upvotes: 0