3

TPT 継承を使用する次のエンティティ フレームワーク モデルを検討してください。

DB テーブル:

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

EF エンティティ:

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

データベースから人のエントリを選択しようとすると、代わりに学生タイプが返されます。

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 テーブルと Student db テーブルの両方からではなく、Person 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はずの方法であるため、インスタンスを受け取りますが、新しいインスタンスを作成して元のインスタンスからデータをコピーしない限り、インスタンスだけを取得することはできません。StudentPersonPersonStudent

EF も同じように機能します。エンティティはアトミックです。スパンするテーブルの数は関係ありません。継承階層を照会すると、常に正しい型のインスタンス全体が取得されます。これは、オブジェクト指向コードが機能するためです。

クエリ内でエンティティのインスタンスを作成しているため、Linq-to-entities で使用した場合、2 番目の例はまったく機能しません。これは許可されていません。データの一貫性が失われる可能性があるため、マッピングされたエンティティに対して射影を行ってはなりません。

行く方法は、非エンティティ型への射影を使用することです-カスタムのマップされていないクラスまたは匿名型。

于 2012-08-30T20:33:01.513 に答える
1

このコードで試してください

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