如何使用实体框架访问子表

本文关键字:访问 框架 何使用 实体 | 更新日期: 2023-09-27 18:33:55

我有以下表格:AnimalConcreteAnimal。如果在这个例子中有任何不同,我将采用数据库优先的方法。假设它们是单独的实体。然后我生成了 2 个DBSet(s),并且可以单独更新任何一个表。一旦我在实体设计器中将ConcreteAnimal设置为Animal的子项,情况就会发生变化。实体设计器中ConcreteAnimal的"实体集"字段变为禁用状态,并自动填充其父类 Animal 的实体集的值。 上下文中不再生成ConcreteAnimal DBSet。这意味着我无法再访问第二个子表。我应该如何将ConcreteAnimal添加到数据库中?这是预期行为吗?如果是,其背后的逻辑是什么?

编辑:好的,我尝试了以下代码,它可以工作。

using(var context = new MyEntities())
{
    var concreteAnimal = new ConcreteAnimal
        {
            //setting properties here
            //both for Animal and specific to ConcreteAnimal
        };
    context.Animals.Add(concreteAnimal);
    context.SaveChanges();
}

奇迹发生了,两个表都填充了正确的数据。这很好。但是,在我看来,为什么我们只为基类DBSet,这看起来不合逻辑?

如何使用实体框架访问子表

您当前正在使用 TPT 继承。

公共信息保存在 Animal 表中,特定类型的特定信息保存在其自己的表中。

您可以在以下文章中找到您正在寻找的信息:

  • 每个层次结构的表 (TPH(
  • 每种类型的表 (TPT(
  • 每个混凝土等级的桌子 (TPC(

编辑

为什么我们只有基类的DBSet

这实际上是一个很好的问题,我不能给出确切的答案,但在我看来,默认情况下没有实现,因为它没有必要并且会非常混乱。

想象一下一些非常复杂的 TPT 场景,其中包含大量继承,它们将为每个具体类提供一个 DbSet(这很容易有数百个额外的 DbSet(,那么现在您将不得不问自己,您必须从哪个 DbSet 中检索、添加或删除此具体类型。

一旦代码生成(在分部类中(,您可以轻松地自己添加代码,并且它将起作用。

public DbSet<ConcreteAnimal> ConcreteAnimals { get; set; }