刚从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()
。
答案 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.
因此看起来亚力克有一个错误: - (