1

我正在尝试从一对多关系中获取一组实体作为 IQueryable,以便在从数据库中获取之前过滤数据。

为了清楚起见,请考虑以下示例:

我目前有一个实体“用户”,其中包含一组图片:

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

图片实体可能属于也可能不属于用户,因此在其定义中没有用户属性。

一个用户可能有数千张图片,但我想选择前 10 张,例如,按 Picture.Id 排序。有没有办法做到这一点?

也许是这样的:

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

谢谢!

4

1 回答 1

4

基本思想是对用户的集合使用OrderByTake方法。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选定用户的所有集合添加到一个列表中,并继续在这个扁平元列表上进行查询。理论上这听起来像是一个相当大的操作,但在这种情况下应该只有一个具有特定 ID 的用户,所以它实际上只是继续选择用户的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 回答