如何在不中断/更改继承策略或行为的情况下将现有实体从 EF 6.1 升级到 EF Core 7?

How do I upgrade the existing entities from EF 6.1 to EF Core 7 without breaking/changing the inheritance strategy or behavior?

提问人:Deepan Maheswaran 提问时间:10/17/2023 最后编辑:Deepan Maheswaran 更新时间:10/17/2023 访问量:53

问:

我在 .NET Framework 上构建了一个现有的 ASP.NET MVC Web 应用程序,该应用程序使用具有代码优先方法的 Entity Framework 6.1 和 SQL Server。

下面显示的实体使用“每个类型一个表”和“每个层次结构一个表”继承策略,这在 Entity Framework 6.1 中没有任何问题。

public abstract class Animal
{
    public string Name { get; set; }
    public int Age { get; set; }

    public abstract void MakeSound();
}

public abstract class Mammal : Animal
{
    public string FurColor { get; set; }

    public abstract void GiveBirth();
}

public class Dog : Mammal
{
    public override void MakeSound()
    {
        Console.WriteLine("Woof! Woof!");
    }

    public override void GiveBirth()
    {
        Console.WriteLine("Dog gives birth to puppies.");
    }
}

public class Cat : Mammal
{
    public override void MakeSound()
    {
        Console.WriteLine("Meow! Meow!");
    }

    public override void GiveBirth()
    {
        Console.WriteLine("Cat gives birth to kittens.");
    }
}

下面是 Fluent API 配置

modelBuilder.Entity<Animal>().ToTable("Animal");

modelBuilder.Entity<Mammal>().ToTable("Mammal")
                .HasDiscriminator<string>("Discriminator")
                .HasValue<Dog>("Dog")
                .HasValue<Cat>("Cat");

modelBuilder.Entity<Dog>().ToTable("Mammal");
            modelBuilder.Entity<Cat>().ToTable("Mammal");

通过上述配置,Entity Framework 6.1 创建了两个表,并在表中包含一个鉴别器。AnimalMammalMammal

问题

但是,当我尝试使用 EF Core 7 重新创建相同的内容时,它失败并出现以下错误:

System.InvalidOperationException:“无法实例化实体类型”Animal“的相应 CLR 类型,但使用”TPC“映射策略将实体类型映射到”Animal”。只应映射可实例化类型。

我知道 EF Core 7.0 中引入了 table-per-concrete-type。但是,它们是否仍支持与 Entity Framework 6.1 相同的实现?

我尝试过:在对 Microsoft 关于 EF Core 继承的文档进行了一些研究之后。我尝试了以下配置,但它们不起作用。

  1. 配置要使用的实体AnimalmodelBuilder.Entity<Animal>().ToTable("Animal").UseTpcMappingStrategy();
  2. 配置要使用的实体MammalHasDiscriminator<string>("MammalType")

问题

如何在不中断/更改继承策略或行为的情况下将上述实体从 EF 6.1 移植/迁移到 EF Core 7?

C# ASP.NET-MVC 实体框架 6 EF-核心 7.0

评论

1赞 Panagiotis Kanavos 10/17/2023
您发布的内容根本不是 Table-per-Concrete 类型。TPC 表示对每种具体类型使用单独的表,即 ,但不是 或 。您发布的内容混合了 Table-per-Type 和 Table-per-Hierarchy。DogCatMammalAnimal
0赞 Panagiotis Kanavos 10/17/2023
鉴于您使用的是 TPT,而不是 TPC,您是否尝试过使用?UseTptMappingStrategy
0赞 Deepan Maheswaran 10/17/2023
@PanagiotisKanavos 你是对的,它使用 TPT 而不是 TPC。我尝试将实体配置为使用“UseTptMappingStategy”,但返回错误The mapping strategy 'TPT' specified on 'Animal' is not supported for entity types with a discriminator
1赞 Deepan Maheswaran 10/18/2023
我咨询了 EF Core 团队,了解到他们不支持在 EF Core 中混合继承策略。有关详细信息,请参阅此 github.com/dotnet/efcore/issues/32077
0赞 Steve Py 10/18/2023
是的,继承对于使用 EF 来说已经有点兔子洞了,混合继承?这是杰克·丹尼尔(Jack Daniel)凌晨2点的水平解决方案设计。;)

答: 暂无答案