使用 Linq 的 Subsonic 3.0.0.3 SQL 分页

问题描述 投票:0回答:3

刚刚从 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()

linq pagination subsonic subsonic3
3个回答
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
投票

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

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


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.

所以 Subsonic 中似乎有一个错误:-(

© www.soinside.com 2019 - 2024. All rights reserved.