使用Linq返回查询中的项目计数及其结果集

我正在使用C#MVC4和Linq。

我已经为我的项目使用了dependency injection,这导致我有一个单独的Model项目以及一个单独的Repository项目(以及一个用于测试ect)。 这一切都没问题。

我将查询从控制器(旧样式)移到存储库(新的DI样式)中,然后注入它们。 它工作正常。

我有一个标准的linq查询(选择任何一个例子,它们足够基本),它正常返回数据库中的一组项目。 这里也没问题。

我的问题是,我想实现分页,而且我教它很简单。 这是我的步骤:

从存储库中获取linq查询的结果(注入到控制器中)将其存储在var中。 它看起来像:

var results = _someInjectedCode.GetListById(SomeId); 

以前,我能够做一些简单的事情:

 results.Count() results.Skip(SomeNum).Take(SomeOtherNum) 

但是现在我想要分页,我需要做我的Skip拿这样的东西:

 var results = from xyz in _someInjectedCode.GetListById(SomeId).SomeId).Skip(SomeNum).Take(SomeOtherNum) select new[] {a,id, a.fName, a.lName .....} 

这样做的问题是,在列表缩短为Pre Skip … Take状态之前,我不再能够访问项目总数,除非我做两个查询,这意味着两次击中DB。

解决此问题的最佳方法是什么。

我就是这样做的:

 var result = (from n in mycollection where n.someprop == "some value" select n).ToList(); var count = result.Count; 

可能还有其他方法,但这是我所知道的最简单的方法。

从SQL的角度考虑它,我想不出在单个普通查询中检索总计数和数据子集的方法,所以我认为你无法在LINQ要么。

为了避免创建两个单独的命令,我只能想到的是一个存储过程,它返回两个表(一个只有count,另一个有你的结果子集)。 它仍然会执行两个查询,但只能在一个连接中执行。 你失去了你的LINQ。 因此,如果您想保留LINQ查询,可能会遇到两个单独的调用。

另一种方法是将整个未分配的结果集检索到内存中,然后针对arrays运行TakeSkip ,但这非常浪费,可能比两次调用更糟糕。

您可以向存储库接口/类添加其他参数,这些参数将提供分页参数并在结果旁边返回计数,或者修改接口以返回IQueryable,然后应用count,然后在编译查询并发送执行之前跳过/ take。