1

データベースからこれをフェッチする前にデータをフィルタリングできるように、1 対多の関係からエンティティのコレクションを IQueryable としてフェッチしようとしています。

明確にするために、次の例を考えてみましょう。

現在、写真のコレクションを持つエンティティ「ユーザー」があります。

public virtual ICollection<Picture> Pictures{ get; set; }

Picture エンティティは、ユーザーに属している場合と属していない場合があるため、定義に User プロパティがありません。

ユーザーは何千もの写真を持っているかもしれませんが、私は最初の 10 枚を選択したいと思います。たとえば、Picture.Id で並べ替えます。これを行う方法はありますか?

たぶん、次のようなものです:

IQueryable<ICollection<Picture>> pictures = context.Users.Where(u=>u.UserId == userId).Select(c => c.Pictures) 

ありがとう!

4

1 に答える 1

4

基本的な考え方は、ユーザーのコレクションでOrderByandTakeメソッドを使用することです。Picturesただし、ユーザーのコレクション全体を読み込まずに、単一のEntityFramework SQLクエリのみを実行するようにしたいのでPictures、これをもう少し具体的な方法で表現する必要があります。

クエリ構文

var result = (from u in users
              where u.Id == userId
               from p in u.Pictures
               orderby p.Id
               select p).Take(10);

メソッド構文

var result = context.Users
    .Where(u => u.Id == 2)
    .SelectMany(u => u.Pictures)
    .OrderBy(p => p.Id)
    .Take(10);

の呼び出しに注意してくださいSelectMany。それは重要です。基本的に、これはPictures選択されたすべてのユーザーのすべてのコレクションを1つのリストに追加し、このフラット化されたメタリストでクエリを続行します。理論的には、これはかなり大きな操作のように聞こえますが、この場合、特定のIDを持つユーザーは1人だけである必要があるため、実際には、選択したユーザーのPicturesコレクションを続行します。生成されるSQLは、単一の高速クエリです。

結果のSQLクエリ(上記の両方)

SELECT TOP (10)
[Extent1].[User_Id] AS [User_Id],
[Extent1].[Id] AS [Id],
[Extent1].[Name] AS [Name]
FROM [dbo].[Pictures] AS [Extent1]
WHERE ([Extent1].[User_Id] IS NOT NULL) AND (2 = [Extent1].[User_Id])
ORDER BY [Extent1].[Id] ASC
于 2012-09-28T11:50:47.073 に答える