2

最初に、いくつかの関連テーブルに含まれているEF4.1コードを使用してデータを取得する必要があります。現在、これを使用する場合

return Context.Set<Entity>()
              .Include(x => x.Children.Select(y => y.GrandChildren.Select(z => z.Child)))
              .Include(x => x.SomeEntity)
              .Include(x => x.AnotherEntity)
              .OrderByDescending(x => x.Id)
              .FirstOrDefault();

データは正しくフェッチされますが、2つのことが心配です。

1)子供/孫を分類する方法がないようです

2)データは1つのテーブルにフラット化されます。つまり、エンティティ(および他のすべての)データはGrandChildレコードごとに複製されます。

質問:

  • 子供/孫を並べ替えるために何をする必要がありますか?
  • 転送されるデータの量は大きくないため、この特定のケースでは2番目のポイント自体は問題にならない可能性があります。30列で最大30レコードです。それでも、Enttity、Children、GrandChildrenを別々にロードして(3つのクエリ)、クライアントサイトに参加させる方法があるかどうか知りたいですか?

返される結果セットは更新可能である必要があります。

4

1 に答える 1

3

子供/孫を並べ替えるために何をする必要がありますか?

アプリケーションでそれらを並べ替えます。それが唯一の信頼できる方法です。Includeは並べ替えをまったく許可しません。また、EFの内部メカニズムを制御できず、ナビゲーションプロパティをSortedList並べ替え順序を維持する他のコレクション(確実に並べ替える必要がある)を使用できないため、以下に示すアプローチは信頼できません。関係)。

データは1つのテーブルにフラット化されます。つまり、エンティティ(および他のすべての)データはGrandChildレコードごとに複製されます。

これは正当な異議です。遅延読み込みをオフにし、個別のクエリを使用してデータを読み込むことで、これを回避できます。

context.Configuration.LazyLoadingEnabled = false;
var parent = context.Set<Entity>().First(e => e.Name = "ABC");
// Load relations in separate query
context.Set<Child>()
       .Where(c => c.Parent.Name == "ABC")
       .OrderBy(c => c.Name) // You can at least try it but as mentioned above it may not work in all scenarios
       .Load();
// Now parent.Children collection should be filled 

他のリレーションやネストされたリレーションについても同じアプローチに従うことができます。Where重要なのは、子供と孫の積み込みの条件を正しく構築することです。

このアプローチがフラット化されたテーブルよりも高速になるという意味ではありません。このアプローチでは、実行されるクエリごとに個別のデータベースラウンドトリップが行われるため、フラット化されたテーブルは、より小さなデータセットでより高速になります。

于 2012-08-12T09:52:46.217 に答える