Я пытаюсь реализовать TPH в EF Core, предположим, у вас есть следующая доменная структура
public abstract class ContainerBase
{
public virtual ICollection<ItemBase> Items { get; set; }
}
public class PlasticContainer : ContainerBase
{
public new ICollection<ColdItem> Items
{
get => base.Items.Cast<ColdItem>().ToList();
set => base.Items = value.Cast<ItemBase>().ToList();
}
}
public class GlassContainer : ContainerBase
{
public new ICollection<HotItem> Items
{
get => base.Items.Cast<HotItem>().ToList();
set => base.Items = value.Cast<ItemBase>().ToList();
}
}
public class ItemBase
{
}
public class ColdItem : ItemBase
{
}
public class HotItem : ItemBase
{
}
и следующая структура DBContext
public DbSet<ContainerBase> Containers { get; set; }
public DbSet<PlasticContainer> PlasticContainers { get; set; }
public DbSet<GlassContainer> GlassContainers { get; set; }
public DbSet<ItemBase> Items { get; set; }
public DbSet<ColdItem> ColdItems { get; set; }
public DbSet<HotItem> HotItems { get; set; }
Проблема, которую я получаю is
System.InvalidOperationException : The specified field '<Items>k__BackingField' of type 'ICollection<ItemBase>' cannot be used for the property 'PlasticContainer.Items' of type 'ICollection<ColdItem>'. Only backing fields of types that are assignable from the property type can be used.
Stack Trace:
PropertyBase.IsCompatible(FieldInfo fieldInfo, Type propertyType, Type entityClrType, String propertyName, Boolean shouldThrow)
PropertyBase.SetFieldInfo(FieldInfo fieldInfo, ConfigurationSource configurationSource)
BackingFieldConvention.Apply(PropertyBase propertyBase)
BackingFieldConvention.Apply(InternalRelationshipBuilder relationshipBuilder, Navigation navigation)
ImmediateConventionScope.OnNavigationAdded(InternalRelationshipBuilder relationshipBuilder, Navigation navigation)
RunVisitor.VisitOnNavigationAdded(OnNavigationAddedNode node)
OnNavigationAddedNode.Accept(ConventionVisitor visitor)
ConventionVisitor.Visit(ConventionNode node)
ConventionVisitor.VisitConventionScope(ConventionScope node)
ConventionScope.Accept(ConventionVisitor visitor)
ConventionVisitor.Visit(ConventionNode node)
ConventionVisitor.VisitConventionScope(ConventionScope node)
ConventionScope.Accept(ConventionVisitor visitor)
ConventionVisitor.Visit(ConventionNode node)
ConventionVisitor.VisitConventionScope(ConventionScope node)
ConventionBatch.Run()
ConventionBatch.Dispose()
InternalModelBuilder.Entity(TypeIdentity& type, ConfigurationSource configurationSource, Boolean allowOwned, Boolean throwOnQuery)
InternalModelBuilder.Entity(Type type, ConfigurationSource configurationSource, Boolean allowOwned, Boolean throwOnQuery)
ModelBuilder.Entity(Type type)
ModelCustomizer.FindSets(ModelBuilder modelBuilder, DbContext context)
RelationalModelCustomizer.FindSets(ModelBuilder modelBuilder, DbContext context)
ModelCustomizer.Customize(ModelBuilder modelBuilder, DbContext context)
RelationalModelCustomizer.Customize(ModelBuilder modelBuilder, DbContext context)
ModelSource.CreateModel(DbContext context, IConventionSetBuilder conventionSetBuilder, IModelValidator validator)
<>c__DisplayClass5_0.<GetModel>b__1()
Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
В нашем проекте есть другие случаи, когда TPH реализован таким способом, который работает нормально, но не этот, обходной путь - не использовать автоматически сгенерированное свойство в базовом классе, а реализовать его самостоятельно с выделенным полем поддержки.
EntityFramework Core 2.2.4
Любая помощь будет принята с благодарностью, спасибо!