0

私は次のモデルを持っています:

public class Person
{
    public int Id { get; set; }
    public virtual ICollection<Category> Categories { get; set; }
}

public class Category
{
    public int Id { get; set; }
    public string Name { get; set; }
}

基本的に1人が複数のカテゴリーに所属できます。そのコードにより、CategoryPerson { PersonId, CategoryID }EF によって作成されたテーブルが作成されました。ここで、すべての人物をすべてのカテゴリとともにリストに表示したいと考えています。単純なアプローチ:

var people = context.People.ToList();
foreach (var p in people)
{
    Console.WriteLine("Person {0}, categories: {1}", p.Id, string.Join("|", p.Categories.Select(x => x.Name)));
}

データベースへの 1 + N リクエストになります。

次のようにインクルードを使用する場合:

var people = context.People.Include(x => x.Categories).ToList();
foreach (var p in people)
{
    Console.WriteLine("Person {0}, categories: {1}", p.Id, string.Join("|", p.Categories.Select(x => x.Name)));
}

リクエストは 1 つしか取得できませんが、これは 2 つのテーブルの結合であり、Person レコードが重く、関連するカテゴリが複数ある場合、同じ重いデータが複数回返されます。

{ person1, category1 } 
{ person1, category2 } 
{ person1, category3 } 

理想的には、データベースへの 2 つの要求を行う必要があります。1 つはすべてのカテゴリを取得するためのもので、もう 1 つはすべての人を取得するためのものです。そして、理想的には、これらの 2 つの配列をメモリ内で結合する必要があります。そのため、Person.Categoriesを列挙すると、データベースには移動せず、代わりにプリロードされたデータが取得されます。これはEFで達成できますか?

4

3 に答える 3

0

EF がこれを行うことはできません。Person_Idただし、テーブルのスキーマのカテゴリのような外部キーを期待/作成します。これを追加Categoryすると、メモリ内で結合できます。

public class Person
{
    public int Id { get; set; }
    public virtual ICollection<Category> Categories { get; set; }
}

public class Category
{
    public int Id { get; set; }
    public int Person_Id { get; set; }
    public string Name { get; set; }
}

var people = context.People.ToList();
var categories = context.Categories.ToList();

foreach (var p in people)
{
    p.Categories = categories.Where(a => a.Person_Id == a.Id);
}
于 2013-10-08T17:29:21.597 に答える
0

まず、モデルに外部キーを含めることを強くお勧めします。ブラインドナビゲーションを避けることをお勧めします。関連エンティティPersonIdのクラスに含める必要があります。Category

第 2 に、EF 5.0 (古いバージョンについてはわかりません) は、メソッドDBSet<T>を介したコンテキストへの完全な読み込みをサポートしています。LoadDBSet に入力した後、プロパティを使用してメモリ内エンティティが必要でLocalあることを指定できます。

context.People.Load();
context.Categories.Load();

var q = (from p in context.People.Local
        join c in context.Categories.Local
        on a.PersonId equals c.PersonId
        select p
        ).ToList(); //--> No round trip to DataBase
于 2013-10-08T17:41:02.247 に答える