sql-server - SQL Server 2008 上的 ServiceStack ORMLite 分页
问题描述
我有一个现有的 SQL Server 2008 数据库,其中包含许多视图、存储过程和函数。
我希望能够SELECT
从这些 SQL 函数之一获取数据并限制它在分页场景中返回的行数。
我尝试使用.Select
with.Skip
和.Take
如下:
public IEnumerable<Product> CallSqlFunction_dbo_Search_Products_View(int clientId,
string environmentCode,
int sessionId)
{
IEnumerable<Product> results;
using (var db = _dbConnectionFactory.Open())
{
results = db.Select<Product>(@"
SELECT
*
FROM
[dbo].[Search_Products_View]
(
@pClientID,
@pEnvironmentCode,
@pSessionId
)", new
{
pClientID = clientId,
pEnvironmentCode = environmentCode,
pSessionId = sessionId
})
.Skip(0)
.Take(1000);
db.Close();
}
return results;
}
这将生成以下 SQL,该 SQL 在 SQL Server 上执行。
exec sp_executesql N'
SELECT
*
FROM
[dbo].[Search_Products_View]
(
@pClientID,
@pEnvironmentCode,
@pSessionId
)',N'@pClientID int,@pEnvironmentCode varchar(8000),@pSessionId int',@pClientID=0,@pEnvironmentCode='LIVE',@pSessionId=12345
这意味着此查询返回 134,000 个产品,而不是我期望的 1000 个产品的第一页。一旦 SQL Server 返回 134,000 行,就会在 API 服务器上进行分页。
是否可以使用 ORMLite 以便我可以在查询中生成类似于以下内容的分页:
exec sp_executesql N'
SELECT
[t1].*
FROM (
SELECT
ROW_NUMBER() OVER (ORDER BY [t0].[ProductId], [t0].[ProductName])
FROM
[dbo].[Search_Products_View](@pClientId, @pEnvironmentCode, @pSessionId) AS [t0]
WHERE
(LOWER([t0].[ProductStatus]) = @pProductStatus1) OR (LOWER([t0].[ProductStatus]) = @pProductStatus2) OR (LOWER([t0].[ProductStatus]) = @pProductStatus3)
) AS [t1]
WHERE
[t1].[ROW_NUMBER] BETWEEN @pPageNumber + 1 AND @pPageNumber + @pNumberOfRowsPerPage
ORDER BY [t1].[ROW_NUMBER]',
N'@pClientId decimal(9,0),@pEnvironmentCode char(3),@pSessionId decimal(9,0),@pProductStatus1 varchar(8000),@pProductStatus2 varchar(8000),@pProductStatus3 varchar(8000),@pPageNumber int,@pNumberOfRowsPerPage int',
@pClientId=0,@pEnvironmentCode='LIVE',@pSessionId=12345,@pProductStatus1='1',@pProductStatus2='2',@pProductStatus3='3',@pPageNumber=0,@pNumberOfRowsPerPage=1000
解决方案
OrmLite 将使用 <= SQL Server 2008 中的窗口函数 hack 进行类型化查询,但不适用于自定义 SQL。您需要将整个 SQL(包括窗口函数)包含到自定义 SQL 中。
如果您经常这样做,我建议将 Windowing Function SQL Template 包装在扩展方法中,以便您可以轻松地在自定义查询中使用它,例如:
results = db.Select<Product>(@"
SELECT
*
FROM
[dbo].[Search_Products_View]
(
@pClientID,
@pEnvironmentCode,
@pSessionId
)"
.InWindowingPage(0,1000), new
{
pClientID = clientId,
pEnvironmentCode = environmentCode,
pSessionId = sessionId
})
如果你想使用 DB 参数作为偏移量,你需要一些耦合来使用传统的参数名称:
results = db.Select<Product>(@"
SELECT
*
FROM
[dbo].[Search_Products_View]
(
@pClientID,
@pEnvironmentCode,
@pSessionId
)"
.InWindowingPage(), new
{
pClientID = clientId,
pEnvironmentCode = environmentCode,
pSessionId = sessionId,
pPageNumber = 0,
pNumberOfRowsPerPage = 100
})
推荐阅读
- string - Powershell:将带/不带前导数字的字符串转换为整数
- python - torchvision 和 tensorflow-gpu 导入错误
- javascript - JavaScript 中的 var 提升
- python - ReadTheDocs 和 autodoc 在构建过程中找不到我的包
- javascript - 如何使用反应在两个 css 类视图类型之间切换
- opengl - 相机 glm / OpenGL 即时模式的示例
- c# - 使 C# 源代码生成器报告的诊断错误出现在 Visual Studio 编辑器中
- docker - Docker - 无法在端口 80 上公开
- c# - 如何评估 LINQ 中两个异构集之间的集差异?
- javascript - 如何在电子中使用文件对话框?