2011-12-13 7 views
1

http://www.sqlteam.com/article/implementing-table-inheritance-in-sql-serverで示されているテーブル継承機能を実装しました。エンティティフレームワークにインクルード/結合の問題があります

すべての外部キーと制約が適用されます。

私は、人、学生、教師、および親を引き戻すためにEntity Frameworkを使用しています。モデルは次のようになります(すべてのEF固有の属性などはありません)。

public partial class People : EntityObject 
{ 
    public guid PeopleID { get; set; } 
    public int Age { get; set; } /Added for an example query 
    public PeopleParent Parent { get; set; } 
    public PeopleStudent Student { get; set; } 
    public PeopleTeacher Teacher { get; set; } 
} 

は今、私は25歳ですタイプに関係なく、すべての人々、これ以上の100以上のレコードを取得する必要があり、私はすべての参照データを含めます。

IQueryable<People> query = Entities.People.Include("PeopleParent") 
              .Include("PeopleStudent") 
              .Include("PeopleTeacher"); 

query.Where(x => x.Age == 25) 
    .Take(100); 

IEnumerable<People> results = query.ToList(); 

十分に単純なようだが、どのようなテーブル/のEntitySet私が最初に含まれるように設定したことは代わりに右の結果を出していないLEFT OUTER JOININNER JOINを作成します。私のような私のEFクエリを作成します。 (私のニーズのために間違った)

生成TSQL:最初INNER JOINとして使用され、私の問題へのsoluionがあるなどがありますなぜ

SELECT 
    [Limit1].[C1] AS [C1], 
    <A bunch of Limit1 Columns> 
FROM (
    SELECT TOP (100) 
    [Extent1].[PeopleID] AS [PeopleID], 
    <A bunch of Extent1 Columns> 
    [Extent2].[PeopleID] AS [PeopleID1], 
    <A bunch of Extent2 Columns> 
    [Extent3].[PeopleID] AS [PeopleID2], 
    <A bunch of Extent3 Columns> 
    [Extent4].[PeopleID] AS [PeopleID3], 
    <A bunch of Extent4 Columns> 
    1 AS [C1] 
    FROM [rets].[People] AS [Extent1] 
    INNER JOIN [rets].[PeopleParent] AS [Extent2] 
    ON [Extent1].[PeopleID] = [Extent2].[PeopleID] 
    LEFT OUTER JOIN [rets].[PeopleStudent] AS [Extent3] 
    ON [Extent1].[PeopleID] = [Extent3].[PeopleID] 
    LEFT OUTER JOIN [rets].[PeopleTeacher] AS [Extent4] 
    ON [Extent1].[PeopleID] = [Extent4].[PeopleID] 
) AS [Limit1] 

** UPDATE 1 **

私はラディスラフMrnkaのAnswerを使用すると仮定すると、重要なのLINQの変化とラムダの照会のために二つの追加要件があります。

質問:特定のプロパティを持つ特定の人物を検索するにはどうすればよいですか?

( "A" の等級を持つすべての学生)

回答:

context.People.OfType<Student>().Where(s => s.Grade == "A"); 

質問:私は特定のプロパティを持っているすべての人々のために検索する方法を教えてください。

回答(PrimaryFocus = "数学" だすべての学生や教師):

List<People> result = new List<People>(); 
result.AddRange(context.People.OfType<Student>() 
           .Where(x => x.PrimaryFocus == "Math") 
           .ToList()); 
result.AddRange(context.People.OfType<Teacher>() 
           .Where(x => x.PrimaryFocus == "Math") 
           .ToList()); 

答えて

6

あなたが相続のネイティブEFサポートを使用しなければならないための明白な解決策。あなたの場合TPT inheritance。あなたは継承をしたら、あなたは単に呼び出します。

IEnumerable<People> results = Entities.People 
             .Where(x => x.Age == 25) 
             .Take(100) 
             .ToList(); 

そして、それは唯一のアドバイスは関係がオプションであることを確認しているソリューションであなたになど

Studentのインスタンス、TeachersParentsを返します(1 - 0..1) - 。必要な場合はINNER JOINを使用します。オプションで、まだINNER JOINを使用している場合は、モデルにバグやその他の問題がある可能性があります。

+0

私はEFで継承サポートを使用していません。私がこの「ウサギの穴」を継承するために下に行くことを選んだ場合、「.Where(x => x.Grade == "A")」を探すと、検索にどのような影響がありますか?親と教師にはGradeプロパティ(学生のみ)? –

+0

'人物 'を検索することはできませんが、' Students': 'context.People.OfType ().Where(s => s.Grade ==" A ")'で検索できます。継承は扱いにくく、パフォーマンスに大きなコストがあります(これは.NET 4.5では改善されます)が、データベースに最適なソリューションです。 –

+0

最後に、私は実際の質問を更新しました。 –

関連する問題