使用Linq的Subsonic 3.0.0.3 SQL分页

时间:2009-08-31 21:20:49

标签: linq subsonic subsonic3 paging

刚从Subsonic 2.2 ActiveRecord更新到3.0.0.3。我正在尝试使用LINQ来执行这样的分页查找查询(我的对象/表称为“存储库”):

Repository.Find(item => item.DocumentTitle.Contains(searchTerm))
    .OrderBy(i => i.DocumentTitle).Skip((currentPage - 1) * itemsPerPage)
    .Take(itemsPerPage);

当我使用SQL Server Profiler查看此查询生成的SQL时,SQL中没有分页,所有分页都在C#的内存中完成。现在,Subsonic查询语言确实有一个很好的GetPaged过程可以正常工作,但我认为LINQ也应该这样做。我在这里错过了什么或者这是LINQ的限制吗?

我知道Repository.GetPaged()函数,但没有足够的参数 - 我需要进行动态排序,以及Find()

3 个答案:

答案 0 :(得分:5)

进行进一步测试后,此语句可正常运行:

(from i in dataContext.Repositories 
 where i.DocumentTitle.Contains(searchTerm) 
 orderby i.DateCreated ascending select i)
 .Skip((currentPage - 1) * itemsPerPage).Take(itemsPerPage);

执行时,上面的linq语句在sql中正确分页。

我能得出的唯一结论是,当你使用方法链语法时,一旦你在初始的lamda表达式之外

Repository.Find(item => item.DocumentTitle.Contains(searchTerm))

亚音速SQL解释器停止为最终链接的任何方法创建SQL

.OrderBy(i => i.DocumentTitle).Skip(15).Take(10);

或者,我在这里完全做错了什么?有人有一些见解吗?

答案 1 :(得分:1)

您可以通过在排序字段中添加“desc”来排序GetPaged,但是......

分页应该工作 - 我正在看我面前的分页SQL,而不是在内存中完成。你是如何测试的?如果您使用将执行查询的“ToList()” - 那么请查看探查器。

答案 2 :(得分:0)

有点晚了但是......

Repository.Find()

返回IList,因此执行查询,因此SQL执行时不进行分页

.Skip(x).Take(x)

在内存中完成。 尝试

Repository.All().Where(expression).Skip(x).Take(x)

所有这些都返回IQueryable,而非枚举对象,因此使用ROW_NUMBER()函数在SQL中完成分页。

说过Subsonic 3简单存储库正在生成以下SQL

exec sp_executesql N'SELECT [t0].[Id], [t0].[IsDeleted], [t0].[Name], [t0].[ParentUuid], [t0].[Uuid]
FROM ( SELECT [t1].[Id], [t1].[IsDeleted], [t1].[Name], [t1].[ParentUuid], ROW_NUMBER() OVER() AS rownum, [t1].[Uuid]
FROM [Sites] AS t1
WHERE (([t1].[ParentUuid] = @p0) AND ([t1].[IsDeleted] = 0))) AS t0
WHERE [t0].[rownum] BETWEEN (20 + 1) AND (20 + 10)',N'@p0 uniqueidentifier',@p0='00000000-0000-0000-0000-000000000000'

引发异常

Unhandled Exception: System.Data.SqlClient.SqlException: The ranking function "ROW_NUMBER" must have an ORDER BY clause.

因此看起来亚力克有一个错误: - (