在LINQ中使用Futures的困難在於像Count這樣的操作會立即執行。
由於@vandalo發現,Count()
之後ToFuture()
實際在內存中運行Count,這是不好的。
在未來的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;
當然,另一種方法是做兩次往返,反正也沒有那麼糟糕。您仍然可以重新使用原來的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();
更新(2011-02-22):我寫了一個blog post關於這個問題,一個更好的解決方案。
使用Session.QueryOver代替 - 這樣可以節省IntelliSense和 'compileability',並有一個SelectCount方法。如果您需要我可以提供使用它的詳細示例 – Genius 2011-02-10 12:03:15
是的,QueryOver似乎也可以正常工作! – Allrameest 2011-02-10 12:56:19
(我在我的解決方案中發現了一個錯誤,並將其刪除以避免混淆,我將很快發佈固定版本) – 2011-02-11 11:26:11