Reputation: 6786
Consider the following entity framework model with TPT inheritance.
DB Tables:
Person (PersonID, Name)
Student (PersonID, Grade)
EF Entities:
Person (PersonID, Name)
Student (Grade) : inherits from Person
Now when you're trying to select a person entry from the database it will return Student type instead.
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
How to force this query select only the data from Person db table and not from both Person and Student db tables?
For example, it can be done with the following query:
db.Persons.Select(x => new Person { PersonID = x.PersonID, Name = x.Name }).First()
but it looks lame, generates an extra SELECT statement over the existing query and this way returned Person entity object will not be tracked by EF context. So, I'm wondering why db.Persons.First()
returns a Student
object? Isn't it counterintuitive?
Upvotes: 3
Views: 1236
Reputation: 364369
If you use a list of Person
and stores a single Student
to the list what will you receive when you call First
? You will receive a Student
instance because that is how object oriented code is supposed to work Student
is a Person
but you will never get just Person
instance without creating a new instance and copying data from original Student
instance.
EF works in the same way - entity is atomic. It doesn't matter how many tables it spans. If you query inheritance hierarchy you will always get the whole instance of the correct type because that is how object oriented code is supposed to work.
Your second example should not work at all if used in Linq-to-entities because you are creating instance of the entity inside the query - that is not allowed. Projections must not be done to mapped entities because it could break data consistency.
The way to go is using projection either to non entity type - custom not mapped class or anonymous type.
Upvotes: 3