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?
If you use a list of
Personand stores a singleStudentto the list what will you receive when you callFirst? You will receive aStudentinstance because that is how object oriented code is supposed to workStudentis aPersonbut you will never get justPersoninstance without creating a new instance and copying data from originalStudentinstance.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.