3

考虑以下具有 TPT 继承的实体框架模型。

数据库表:

Person (PersonID, Name)
Student (PersonID, Grade)

英孚实体:

Person (PersonID, Name)
Student (Grade) : inherits from Person

现在,当您尝试从数据库中选择人员条目时,它将返回 Student 类型。

var person = db.Persons.First();
// person here is of type Student and has Grade peoperty populated
// SQL query generated by EF selects data from both tables with a JOIN

如何强制此查询仅从 Person db 表中选择数据,而不是从 Person 和 Student db 表中选择数据?

例如,可以使用以下查询来完成:

db.Persons.Select(x => new Person { PersonID = x.PersonID, Name = x.Name }).First() 

但它看起来很蹩脚,在现有查询上生成一个额外的 SELECT 语句,这样返回的 Person 实体对象将不会被 EF 上下文跟踪。所以,我想知道为什么要db.Persons.First()返回一个Student对象?这不是违反直觉吗?

4

2 回答 2

3

如果您使用列表Person并将单曲存储Student到列表中,您调用时会收到什么First?您将收到一个Student实例,因为这就是面向对象代码的工作Student方式,但是如果不创建新实例并从原始实例复制数据,Person您将永远不会只获得实例。PersonStudent

EF 以同样的方式工作——实体是原子的。它跨越多少个表并不重要。如果您查询继承层次结构,您将始终获得正确类型的整个实例,因为这就是面向对象代码的工作方式。

如果在 Linq-to-entities 中使用第二个示例,则根本不应该工作,因为您正在查询中创建实体的实例 - 这是不允许的。不能对映射实体进行投影,因为它可能会破坏数据的一致性。

要走的路是对非实体类型使用投影 - 自定义非映射类或匿名类型。

于 2012-08-30T20:33:01.513 回答
1

尝试使用此代码

db.Persons.TypeOf<Person>().First();
于 2012-08-29T22:17:44.893 回答