使用Take运算符时,有没有办法获得整数?
答案 0 :(得分:6)
你可以做到这两点。
IEnumerable<T> query = ...complicated query;
int c = query.Count();
query = query.Take(n);
只需在拍摄前执行计数。这将导致查询执行两次,但我相信这是不可避免的。
如果这是在Linq2SQL上下文中,正如您的注释所暗示的那么这实际上会查询数据库两次。就延迟加载而言,它将取决于查询结果的实际使用方式。
例如:如果您有两个表Product
和ProductVersion
,其中每个Product
都有多个ProductVersions
通过外键关联。
如果这是您的查询:
var query = db.Products.Where(p => complicated condition).OrderBy(p => p.Name).ThenBy(...).Select(p => p);
您只是选择Products
但执行查询后
var results = query.ToList();//forces query execution
results[0].ProductVersions;//<-- Lazy loading occurs
如果您引用任何不属于原始查询的外键或相关对象,那么它将被延迟加载。在您的情况下,计数不会导致任何延迟加载,因为它只是返回一个int。但是根据您对Take()
的结果实际执行的操作,您可能会或可能不会进行延迟加载。有时候很难判断你是否有LazyLoading ocurring,要检查你是否应该使用DataContext.Log
属性来记录你的查询。
答案 1 :(得分:4)
最简单的方法是只执行Count
查询,然后执行Take
:
var q = ...;
var count = q.Count();
var result = q.Take(...);
答案 2 :(得分:2)
可以在单个Linq-to-SQL查询中执行此操作(其中只执行一个SQL语句)。生成的SQL会让看起来不愉快,因此您的性能可能会有所不同。
如果这是您的查询:
IQueryable<Person> yourQuery = People
.Where(x => /* complicated query .. */);
您可以将以下内容添加到其中:
var result = yourQuery
.GroupBy (x => true) // This will match all of the rows from your query ..
.Select (g => new {
// .. so 'g', the group, will then contain all of the rows from your query.
CountAll = g.Count(),
TakeFive = g.Take(5),
// We could also query for a max value.
MaxAgeFromAll = g.Max(x => x.PersonAge)
})
.FirstOrDefault();
您可以这样访问您的数据:
// Check that result is not null before access.
// If there are no records to find, then 'result' will return null (because of the grouping)
if(result != null) {
var count = result.CountAll;
var firstFiveRows = result.TakeFive;
var maxPersonAge = result.MaxAgeFromAll;
}