试图给你一个简短的答案,如果你skip(n).take(m)在linq上执行方法(使用SQL 2005/2008作为数据库服务器),你的查询将使用该Select ROW_NUMBER() Over ...语句,在SQL引擎中以某种方式直接分页。
举个例子,我有一个db表调用mtcity,我编写了以下查询(与linq一起工作到实体):
using (DataClasses1DataContext c = new DataClasses1DataContext())
{
var query = (from MtCity2 c1 in c.MtCity2s
select c1).Skip(3).Take(3);
//Doing something with the query.
}
生成的查询将是:
SELECT [t1].[CodCity],
[t1].[CodCountry],
[t1].[CodRegion],
[t1].[Name],
[t1].[Code]
FROM (
SELECT ROW_NUMBER() OVER (
ORDER BY [t0].[CodCity],
[t0].[CodCountry],
[t0].[CodRegion],
[t0].[Name],
[t0].[Code]) AS [ROW_NUMBER],
[t0].[CodCity],
[t0].[CodCountry],
[t0].[CodRegion],
[t0].[Name],
[t0].[Code]
FROM [dbo].[MtCity] AS [t0]
) AS [t1]
WHERE [t1].[ROW_NUMBER] BETWEEN @p0 + 1 AND @p0 + @p1
ORDER BY [t1].[ROW_NUMBER]
这是一个窗口数据访问(非常酷,顺便说一下cuz将从一开始就返回数据,只要条件满足就会访问表)。这将非常类似于:
With CityEntities As
(
Select ROW_NUMBER() Over (Order By CodCity) As Row,
CodCity //here is only accessed by the Index as CodCity is the primary
From dbo.mtcity
)
Select [t0].[CodCity],
[t0].[CodCountry],
[t0].[CodRegion],
[t0].[Name],
[t0].[Code]
From CityEntities c
Inner Join dbo.MtCity t0 on c.CodCity = t0.CodCity
Where c.Row Between @p0 + 1 AND @p0 + @p1
Order By c.Row Asc
除了这个例外,第二个查询将比linq结果执行得更快,因为它将专门使用索引来创建数据访问窗口; 这意味着,如果您需要一些过滤,过滤应该(或必须)在Entity列表中(创建行的位置),并且还应创建一些索引以保持良好的性能。
现在,哪个更好?
如果您的逻辑中有非常可靠的工作流程,那么实现正确的SQL方法将会很复杂。在这种情况下,LINQ将成为解决方案。
如果你可以将逻辑中的那部分直接降低到SQL(在存储过程中),它会更好,因为你可以实现我向你展示的第二个查询(使用索引)并允许SQL生成并存储执行计划查询(提高性能)。