2

バックグラウンド

親の Name プロパティと子の ID のリストを含む親子関係からプロジェクションを作成しています。

コード

private class ParentChildInfo
{
    public string Name { get; set; }
    public List<int> ChildIds { get; set; }
}

var infos = ctx.Masters.Include(m => m.Children).Select(
    m => new ParentChildInfo()
    {
        Name = m.Name,
        ChildIds = m.Children.Where(c => c.SomeProp.StartsWith("SpecialValue"))
                    .Select(c => c.Id).ToList()
    }).ToList();

残念ながら、それはエラーを生成しました

LINQ to Entities がメソッド 'System.Collections.Generic.List`1[System.Int32] ToList[Int32] を認識しない

それが私をこの投稿に導き、(コメントで)次の変更を行うことを提案しました:

private class ParentChildInfo
{
    public string Name { get; set; }
    public IEnumerable<int> ChildIds { get; set; } // No longer List<int>
}

var infos = ctx.Masters.Include(m => m.Children).Select(
    m => new ParentChildInfo()
    {
        Name = m.Name,
        ChildIds = m.Children.Where(c => c.SomeProp.StartsWith("SpecialValue"))
                    .Select(c => c.Id) // Dropped the .ToList()
    }).ToList();

結果を使用するコードは数分間実行され、DbContext をそれほど長く拘束したくなかったため、元々列挙型ではなくリストを取得したかったのです。

私は次のようなコードを使用します:

using (MyContext ctx = new MyContext())
{
    // code from above that populates infoes
}

foreach (var info in infoes)
{
    // use info.ChildIds
}

ChildIds を列挙できるように をに移動する予定でしたがforeach、代わりに F5 キーを押して、コードが機能することに驚きました。using

質問

DbContext がその時点で破棄され、ChildIds がIEnumerable<int>ではなく であるとすればList<int>、なぜ ChildIds を正確に列挙できるのでしょうか?

4

2 に答える 2

3

これはToList()infosクエリの が実際にクエリを実行するためです。したがって、コレクションctx.Mastersが列挙され、プロジェクションが入力されます。なくても対処Includeされていることに気づきMaster.Children、SQL 結合を発行します。の実装タイプIEnumerable<int> ChildIdsはおそらくList<int>です。

于 2013-03-27T19:47:01.070 に答える
1

クエリで .ToList() を実行したため、クエリが実行され、すべての結果が具体化され、データベースへの接続が閉じられるはずです。.ToList() がなければ (少なくとも EF5 では) 結果はストリーミング方式で処理され、エンティティは要求時に (つまり、ループ内の各反復で) 実体化されるため、機能しないと思います。

于 2013-03-27T19:48:09.643 に答える