3

Aオブジェクトのセット ( ) と多数の関連オブジェクト ( B) を 1 つのクエリで取得したいと考えています。にはナビゲーション プロパティがないため、次の構文を使用する必要があるAB思います。

select a from db.As where a.Id = x select new AndBHolder
{
   A = a,
   Bs = select b from db.Bs where b.ASomeId == A.SomeId select b
}

これが最善の方法かどうかはわかりませんが、うまくいきます。Bただし、 (のリスト)のプロパティを含める必要がありますCs。うまくいくとは思っていませんでしたが、試してみました:

select a from db.As where a.Id = x select new AndBHolder
{
   A = a,
   Bs = select b from db.Bs.Include("Cs") where b.ASomeId == A.SomeId select b
}

「メソッド...タイプで宣言されたインクルード...タイプのインスタンスで呼び出すことはできません...」で失敗します。次に、プロジェクション内でプロジェクションを試してみようと思いました:

select a from db.As where a.Id = x select new AndBHolder
{
   A = a,
   Bs = select b from db.Bs where b.ASomeId == A.SomeId select new B
        {
           Id = b.Id,
           // ...
           Cs = select c from db.Cs where c.BId == b.Id select c
        }
}

マップされたオブジェクトへの投影が許可されていないため、 「エンティティまたは複合型 ' B' は LINQ to Entities クエリで構築できません」で失敗します。Bsでは、データが入力された状態でを取得するにはどうすればCsよいですか? または、セカンダリ レベルの包含はサポートされていませんか? データベースに対して 2 つの呼び出しを行う必要がありますか? 1 つは As を取得し、もう 1 つはBsそのCs

4

1 に答える 1

3

select newもう使用できないプロジェクションを使用するIncludeと、無視されます。代わりに、関連エンティティを投影データに追加する必要があります。次に例を示します。

var query = from a in db.As
            join b in db.Bs on a.SomeId equals b.ASomeId into bGroup
            where a.Id = x
            select new AndBHolder
            {
                A = a,
                Bs = bGroup, // Bs must be of type IEnumerable<B>
                Cs = bGroup.SelectMany(bg => bg.Cs) // Cs is IEnumerable<C>
            };

Bとの関係Cが 1 対多 (多対多ではない) の場合、EF は自動的Csにロードされるたびにコレクションを作成する必要があります (これは「関係修正」と呼ばれます)。つまり、データの後に射影から をB捨てることができます。Csデータベースからロードされています。これをまとめるには、次のようにクエリを記述してみてください。

var query = (from a in db.As
             join b in db.Bs on a.SomeId equals b.ASomeId into bGroup
             where a.Id = x
             select new
             {
                 A = a,
                 Bs = bGroup,
                 Cs = bGroup.SelectMany(bg => bg.Cs)
             })
             .AsEnumerable() // DB query gets executed here
             .Select(y => new AndBHolder
             {
                 A = y.A,
                 Bs = y.Bs // the Cs in every B should be populated here
             });
于 2012-07-21T16:45:10.570 に答える