我正在尝试从一对多关系中获取一组实体作为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)
谢谢!
答案 0 :(得分:4)
基本思路是在用户的OrderBy
集合上使用Take
和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