EF Core 中 TPC 策略的抽象基类是否支持复杂类型?

问题描述 投票:0回答:1

总结

我尝试在 EF Core 中实现层次结构,其中使用 TPC 策略并在抽象基类中具有复杂类型。我也使用迁移。 关键词:net8.0、Visual Studio Professional 2022、迁移

描述

我的用例非常适合 EF Core 中的 TPC 策略。一些属性应该存在于所有具体类中,并且自然地分组在不同的簇中。这非常适合抽象基类中的复杂类型,但问题是我无法使其工作。 当我声明和配置复杂类型时,我没有收到编译器的任何抱怨,但在生成初始迁移后,迁移中的具体类型中没有复杂类型的迹象。我在文档中找不到任何表明这是不可能的内容。有人在 TPC 策略中使用复杂类型取得过成功吗?如果是的话,您是如何使其发挥作用的? 我不是 EF Core 的高级用户,所以如果这是一个微不足道的问题,我提前道歉!

示例

public abstract class AbstractBaseClass
{
    public MyComplexType MyComplexProperty {get;set;}
}

public class ContextConfiguration
{
    public void Configure(EntityTypeBuilder<AbstractBaseClass> builder)
    {
        builder.ComplexProperty(c => c.MyComplexProperty).IsRequired();
    }
}
c# entity-framework migration tpc
1个回答
-1
投票

在 Entity Framework Core (EF Core) 中使用抽象基类中的复杂类型的 Table Per Concrete Type (TPC) 继承策略时,您似乎遇到了困难。

EF Core 不直接支持 TPC 继承场景中复杂类型到具体类型的映射。因此,抽象基类中定义的复杂类型不会包含在具体类型的迁移中。

要解决此问题,请考虑替代方法:

  1. 每个层次结构表 (TPH): 在 TPH 中,层次结构中的所有类型都映射到单个表。虽然这可能与您对每个具体类的不同表的偏好不一致,但它允许包含在基本抽象类中定义的复杂类型。

  2. 每个类型的表(TPT):TPT 将层次结构中的每个类型映射到其自己的表,类似于 TPC。然而,TPT 也不直接支持在抽象基类中定义的复杂类型。

考虑到这些限制,您可能需要重新评估您的数据建模方法。一种可能的选择是为每个具体类定义单独的复杂类型,而不是在抽象基类中使用共享的复杂类型。

这是一个例子:

public abstract class AbstractBaseClass
{
    // Define separate complex types for each concrete class
    public ConcreteClassComplexType ConcreteClassProperty { get; set; }
    public AnotherConcreteClassComplexType AnotherConcreteClassProperty { get; set; }
}

public class ConcreteClass : AbstractBaseClass
{
    // Additional properties specific to ConcreteClass
}

public class AnotherConcreteClass : AbstractBaseClass
{
    // Additional properties specific to AnotherConcreteClass
}

public class YourDbContext : DbContext
{
    public DbSet<AbstractBaseClass> BaseClasses { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<AbstractBaseClass>().ToTable("BaseClasses");
        modelBuilder.Entity<ConcreteClass>().ToTable("ConcreteClasses");
        modelBuilder.Entity<AnotherConcreteClass>().ToTable("AnotherConcreteClasses");

        // Configure complex types
        modelBuilder.Entity<AbstractBaseClass>().OwnsOne(c => c.ConcreteClassProperty);
        modelBuilder.Entity<AbstractBaseClass>().OwnsOne(c => c.AnotherConcreteClassProperty);
    }
}

在这个例子中,每个具体类(ConcreteClass、AnotherConcreteClass)都有自己的复杂类型,可以在 OnModelCreating 方法中单独配置。虽然此方法可能需要更多配置,但它允许在 EF Core 中使用具有 TPC 继承的复杂类型。

© www.soinside.com 2019 - 2024. All rights reserved.