c# – 如何使用Entity Framework访问子表

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

编辑:
好的,我尝试了下面的代码,它的工作原理.

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表中,特定信息保存在自己的表中.

您将在这些文章中找到您正在查找的信息:

> Table per Hierarchy (TPH)
> Table per Type (TPT)
> Table per Concrete class (TPC)

编辑

Why we have DBSet for base class only

这实际上是一个很好的问题,我无法给出一个确切的答案,但从我的观点来看,这并不是默认实现的,因为它没有必要,而且会非常混乱.

想象一下具有大量继承的一些非常复杂的TPT场景,他们会为每个具体的类都有一个DbSet(可能很容易就是一百个额外的DbSet),那么现在你将不得不问自己,你从哪个DbSet检索,添加或删除此具体类型.

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

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