Entity framework EF:一对多关系-查询数据子集

Entity framework EF:一对多关系-查询数据子集,entity-framework,lazy-loading,Entity Framework,Lazy Loading,我正在尝试从一对多关系中获取实体集合作为IQueryable,以便在从数据库获取之前过滤数据 为了说明清楚,请考虑下面的例子: 我目前有一个实体“用户”,它有一组图片: public virtual ICollection<Picture> Pictures{ get; set; } 公共虚拟ICollection图片{get;set;} 图片实体可能属于用户,也可能不属于用户,因此在其定义中没有用户属性 一个用户可能有数千张图片,但我想选择前10张,例如,按Picture.Id

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

为了说明清楚,请考虑下面的例子:

我目前有一个实体“用户”,它有一组图片:

public virtual ICollection<Picture> Pictures{ get; set; }
公共虚拟ICollection图片{get;set;}
图片实体可能属于用户,也可能不属于用户,因此在其定义中没有用户属性

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

也许是这样的:

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

谢谢

基本思想是在用户的
图片集上使用
OrderBy
Take
方法。但是,由于您希望确保只执行单个EntityFramework SQL查询,而不加载用户的整个
图片
集合,因此需要以稍微更具体的方式来表示

查询语法

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);
方法语法

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);
注意调用
选择many
。这很重要。基本上,这会将所有选定用户的所有
图片
集合添加到一个列表中,并继续在这个平坦的元列表上进行查询。从理论上讲,这听起来像是一个相当大的操作,但在这种情况下,应该只有一个用户具有特定的ID,因此它实际上只是继续使用所选用户的
图片集。生成的SQL是一个单一的快速查询:

结果SQL查询(用于上述两种查询)


基本思想是在用户的
图片集上使用
OrderBy
Take
方法。但是,由于您希望确保只执行单个EntityFramework SQL查询,而不加载用户的整个
图片
集合,因此需要以稍微更具体的方式来表示

查询语法

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);
方法语法

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);
注意调用
选择many
。这很重要。基本上,这会将所有选定用户的所有
图片
集合添加到一个列表中,并继续在这个平坦的元列表上进行查询。从理论上讲,这听起来像是一个相当大的操作,但在这种情况下,应该只有一个用户具有特定的ID,因此它实际上只是继续使用所选用户的
图片集。生成的SQL是一个单一的快速查询:

结果SQL查询(用于上述两种查询)


这会是数据密集型的吗?就像在中一样,这会带来所有数千张照片,然后订购并拍摄我想要的照片吗?或者它是懒惰的,并且只选择我请求的图片,例如,前10张图片Linq尽可能懒惰。如果这是一个CLR对象集合或一个SQL数据库-是的,它是懒惰的!如果不是,LINQ2SQL将毫无用处实际上,这个LINQ表达式只有在你强制它变为LINQ表达式时才会被计算——要么用
.ToList()
标记它,要么通过迭代器块访问它。所以如果我使用第一行,它会计算所有图片?正如在中一样,context.Users.Single(u=>u.UserId==UserId).Pictures.OrderBy(p=>p.Id).Take(10)不是懒惰的,而第二块代码(在LINQ下是懒惰的?)哦-不-两者都是懒惰的!只是输入(基本上)相同内容的不同方式。这只是品味的问题。:)关于LINQ和延迟加载的一本好书:我整个周末都在考虑这个问题,我被方法语法没有给我相同的结果这一事实激怒了。所以我决定想办法。有关激动人心的结论,请参见我编辑的答案。:)这会是数据密集型的吗?就像在中一样,这会带来所有数千张照片,然后订购并拍摄我想要的照片吗?或者它是懒惰的,并且只选择我请求的图片,例如,前10张图片Linq尽可能懒惰。如果这是一个CLR对象集合或一个SQL数据库-是的,它是懒惰的!如果不是,LINQ2SQL将毫无用处实际上,这个LINQ表达式只有在你强制它变为LINQ表达式时才会被计算——要么用
.ToList()
标记它,要么通过迭代器块访问它。所以如果我使用第一行,它会计算所有图片?正如在中一样,context.Users.Single(u=>u.UserId==UserId).Pictures.OrderBy(p=>p.Id).Take(10)不是懒惰的,而第二块代码(在LINQ下是懒惰的?)哦-不-两者都是懒惰的!只是输入(基本上)相同内容的不同方式。这只是品味的问题。:)关于LINQ和延迟加载的一本好书:我整个周末都在考虑这个问题,我被方法语法没有给我相同的结果这一事实激怒了。所以我决定想办法。有关激动人心的结论,请参见我编辑的答案。:)