如何使用实体框架访问子表
本文关键字:访问 框架 何使用 实体 | 更新日期: 2023-09-27 18:33:55
我有以下表格:Animal
和ConcreteAnimal
。如果在这个例子中有任何不同,我将采用数据库优先的方法。假设它们是单独的实体。然后我生成了 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; }