0

Entity Framework 5 を使用して C# (.NET 4.5) で単純なデータベース アプリケーションを作成しています。単一のエンティティの関連エンティティを読み込む必要がある場合と必要でない場合があります。エンティティの関連エンティティをロードする必要がある場合は、関連エンティティの関連エンティティを熱心にロードしたいと考えています。基本的に、「SELECT N + 1」の問題を回避しようとしています。うまくいけば、次のコードで私がやろうとしていることを明確にすることができます:

using (var ctx = new DbContext())
{
    // Find a single instance of a person.  I don't want to eagerly load
    // the person's friends at this point because I may not need this
    // information.
    var person = ctx.Persons.Single(x => x.PersonID == 12);

    // Many lines of code...
    // Many lines of code...
    // Many lines of code...

    // Okay, if we have reached this point in the code, the person wants to 
    // send all his friends a postcard, so we need the person's friends and
    // their addresses.

    // I want to eagerly load the person's friends' addresses, but the Include
    // method is not allowed.  The property "Friends" is just an ObservableCollection.
    var friends = person.Friends.Include("Address").ToList();

    // So, I must do the following:
    var friends = person.Friends.ToList();

    // Now I will output the address of each friend. This is where I have the 
    // SELECT N+1 problem.
    foreach(var friend in friends)
    {
        // Every time this line is executed a query (SELECT statement) is sent
        // to the database.
        Console.WriteLine(friend.Address.Street);

    }

}

私が何をすべきかについてのアイデアはありますか?

4

1 に答える 1

1

これは、明示的な読み込みに適した状況です。関連するエンティティを Entity Framework で読み込むための 3 つ目のオプションは、熱心な読み込みと遅延読み込みに加えて、次のとおりです。

using (var ctx = new DbContext())
{
    var person = ctx.Persons.Single(x => x.PersonID == 12);

    // ...

    // the following issues one single DB query
    person.Friends = ctx.Entry(person).Collection(p => p.Friends).Query()
        .Include(f => f.Address) // = .Include("Address")
        .ToList();

    foreach(var friend in person.Friends)
    {
        // No DB query because all friends including addresses
        // have already been loaded
        Console.WriteLine(friend.Address.Street);
    }
}

ここで重要なのは、コレクションに対してクエリ.Query()可能なものを返し、Friends友人コレクションに任意の追加クエリ ロジックを追加できるようにすることです。たとえば、フィルタリング、順序付け、追加の関連データの結合 (= Include)、集計 (Count友人など) などです。

于 2013-05-10T21:37:38.967 に答える