我尝试在 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();
}
}
在 Entity Framework Core (EF Core) 中使用抽象基类中的复杂类型的 Table Per Concrete Type (TPC) 继承策略时,您似乎遇到了困难。
EF Core 不直接支持 TPC 继承场景中复杂类型到具体类型的映射。因此,抽象基类中定义的复杂类型不会包含在具体类型的迁移中。
要解决此问题,请考虑替代方法:
每个层次结构表 (TPH): 在 TPH 中,层次结构中的所有类型都映射到单个表。虽然这可能与您对每个具体类的不同表的偏好不一致,但它允许包含在基本抽象类中定义的复杂类型。
每个类型的表(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 继承的复杂类型。