All*_*est 18 linq nhibernate linq-to-nhibernate
我想在编写Linq查询时使用NHibernate进行分页.做这样的事情很容易:
return session.Query<Payment>()
.OrderByDescending(payment => payment.Created)
.Skip((page - 1)*pageSize)
.Take(pageSize)
.ToArray();
Run Code Online (Sandbox Code Playgroud)
但有了这个,我没有得到任何关于项目总数的信息.如果我只是做一个简单的.Count(),那将生成一个对数据库的新调用.
我发现这个答案通过使用未来来解决它.但它使用Criteria.我怎么能用Linq做到这一点?
Die*_*hon 30
将Futures与LINQ一起使用的困难在于像Count这样的操作会立即执行.
作为@vandalo发现,Count()经过ToFuture()实际运行在内存中的计数,这是不好的.
在未来的LINQ查询中获取计数的唯一方法是GroupBy在不变字段中使用.一个很好的选择是已经成为过滤器的一部分(比如"IsActive"属性)
这是一个例子,假设您在付款中有这样的属性:
//Create base query. Filters should be specified here.
var query = session.Query<Payment>().Where(x => x.IsActive == 1);
//Create a sorted, paged, future query,
//that will execute together with other statements
var futureResults = query.OrderByDescending(payment => payment.Created)
.Skip((page - 1) * pageSize)
.Take(pageSize)
.ToFuture();
//Create a Count future query based on the original one.
//The paged query will be sent to the server in the same roundtrip.
var futureCount = query.GroupBy(x => x.IsActive)
.Select(x => x.Count())
.ToFutureValue();
//Get the results.
var results = futureResults.ToArray();
var count = futureCount.Value;
Run Code Online (Sandbox Code Playgroud)
当然,替代方案是进行两次往返,这无论如何都不是那么糟糕.您仍然可以重用原始的IQueryable,这在您想要在更高级别的层中进行分页时非常有用:
//Create base query. Filters should be specified here.
var query = session.Query<Payment>();
//Create a sorted, paged query,
var pagedQuery = query.OrderByDescending(payment => payment.Created)
.Skip((page - 1) * pageSize)
.Take(pageSize);
//Get the count from the original query
var count = query.Count();
//Get the results.
var results = pagedQuery.ToArray();
Run Code Online (Sandbox Code Playgroud)
更新(2011-02-22):我写了一篇关于这个问题的博客文章和一个更好的解决方案.