如何将使用ROW_NUMBER()的查询转换为linq
本文关键字:查询 转换 linq NUMBER ROW | 更新日期: 2023-09-27 18:24:18
我的表由三列组成(sno、name、age)。我从带有额外列(行号)的数据库中检索此表,并使用了以下代码:
select * from (
select ROW_NUMBER() over (order by SNo asc)as rowindex,SNo,Name,Age
from tblExample)
as example where rowindex between ((pageindex*10)+1) and ((pageindex+1)*10)
注意,pageindex是一个变量,它取一些由用户传递的整数值。
我的数据库是Sql Server 2008。我想使用Linq编写相同的查询。我该怎么做?
您可以将查询写为beow
var index=1;
var pageIndex=1;
var pageSize = 10;
data.Select(x => new
{
RowIndex = index++,
Sno = x.Sno,
Name = x.Name,
Age = x.Age
}).OrderBy(x => x.Name)
.Skip(pageSize * (pageIndex - 1)).Take(pageSize).ToList();
不是直接翻译,但由于您的行号似乎只用于分页,请尝试:
db.tblExample
.OrderBy(t => t.SNo)
.Select((t,i) => new {rowindex = i+1, t.SNo, t.Name, t.Age })
.Skip(pageIndex * 10)
.Take(10);
编辑
如果Select((t,i) => ...)
不起作用,您可以尝试在对查询进行水合后添加索引号来合成索引号:
db.tblExample
.OrderBy(t => t.SNo)
.Skip(pageIndex * 10)
.Take(10)
.AsEnumerable();
.Select((t,i) => new {rowindex = (pageIndex*10)+i+1, t.SNo, t.Name, t.Age })
除了rowindex
字段不会从SQL查询中返回,而是由成员选择表达式添加之外,您最终应该得到等效的SQL。
最佳情况场景(如果需要元数据):
var rows = db.tblExample // database context
.OrderBy(x => x.SNo) // set an orderby
.AsEnumerable() // force query execution (now we have local dataset)
.Select(x => new
{
rowindex = i,
SNo = x.Sno,
Name = x.Name,
Age = x.Age
}); // now you have your original query
这里唯一的缺点是必须提取整个数据集才能获得此元数据。但是,如果使用.Skip
&.Take
和LINQ会自动将其转换为行号(您以后将无法使用该元数据)。例如
var pageIndex = /* ??? */;
var rows = db.tblExample
.OrderBy(x => x.SNo)
.Skip(pageIndex * 10).Take(10);
它应该会给你这样的东西:
SELECT [t1].[SNo] AS [SNo],
[t1].[Name] AS [Name],
[t1].[Age] AS [Age]
FROM (
SELECT ROW_NUMBER() OVER (ORDER BY [t0].[tblExample], [t0].[SNo]) AS [ROW_NUMBER],
[t0].[SNo],
[t0].[Name],
[t0].Age]
FROM [tblExample] AS [t0]
) AS [t1]
WHERE [t1].[ROW_NUMBER] BETWEEN @p0 + 1 AND @p0 + @p1
ORDER BY [t1].[ROW_NUMBER]
因此,现在row_number
在SQL内部使用,但您无法在代码中访问它。
如果您真的想要这种访问,那么最好手动将查询发送到服务器。一个能很好地处理这类事情的库是dapper dot net,它看起来像:
class MyObject {
public Int32 rowindex;
public Int32 SNo;
public String Name;
publig Int32 Age;
}
/* build "connection" */
connection.Query<MyObject>("SELECT * FROM (SELECT ROW_NUMBER() ... ) ...");