C# 如何将使用ROW_NUMBER()的查询转换为linq?

C# 如何将使用ROW_NUMBER()的查询转换为linq?,c#,linq,C#,Linq,我的表由三列组成:sno、name、age。我使用额外的列行号从数据库中检索此表,并使用以下代码: 从中选择* 按SNo ascas rowindex、SNo、名称、年龄选择订单上的行号 来自tblExample 例如,其中pageindex*10+1和pageindex+1*10之间的rowindex 注意,pageindex是一个变量,它接受用户传递的某个整数值 我的数据库是SQLServer2008。我想使用Linq编写相同的查询。如何做到这一点?不是直接翻译,但由于您的行号似乎仅用于分页

我的表由三列组成:sno、name、age。我使用额外的列行号从数据库中检索此表,并使用以下代码:

从中选择* 按SNo ascas rowindex、SNo、名称、年龄选择订单上的行号 来自tblExample 例如,其中pageindex*10+1和pageindex+1*10之间的rowindex 注意,pageindex是一个变量,它接受用户传递的某个整数值

我的数据库是SQLServer2008。我想使用Linq编写相同的查询。如何做到这一点?

不是直接翻译,但由于您的行号似乎仅用于分页,请尝试:

db.tblExample
  .OrderBy(t => t.SNo)
  .Select((t,i) => new {rowindex = i+1, t.SNo, t.Name, t.Age })
  .Skip(pageIndex * 10)
  .Take(10);
编辑

如果选择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 })

除了从SQL查询中不会返回rowindex字段,而是由成员选择表达式添加之外,您应该得到等效的SQL。

您可以按如下方式编写查询

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();
如果您需要元数据,请选择最佳方案:

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将自动将其转换为一个行号,您以后将无法使用该元数据。e、 g

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]
class MyObject {
    public Int32 rowindex;
    public Int32 SNo;
    public String Name;
    publig Int32 Age;
}

/* build "connection" */

connection.Query<MyObject>("SELECT * FROM (SELECT ROW_NUMBER() ... ) ...");
现在,行号在SQL内部使用,但您无法在代码中访问它

如果您确实需要这种访问,最好手动将查询发送到服务器。一个适合这种类型的库是,它看起来像:

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]
class MyObject {
    public Int32 rowindex;
    public Int32 SNo;
    public String Name;
    publig Int32 Age;
}

/* build "connection" */

connection.Query<MyObject>("SELECT * FROM (SELECT ROW_NUMBER() ... ) ...");

LINQ到SQL?LINQ到EF?不拉动整个集合,可能使用变量或重载。Select运算符,我不相信有LINQ命令可以转换为这个查询。表达式树可能不包含赋值运算符。如果不首先在本地缓存列表,这对您来说到底是如何工作的?@Simon Belanger:他的要求是在LINQ的帮助下在网格视图中动态分页。在这种情况下,上述场景非常有效。请自己尝试,因为它可以完美地工作。如果不使用.SelectFunc重载来生成用于查询运算符“Select”的查询不受支持的重载,则必须首先将结果存储在本地。因此,如果这是一个DB上下文,您必须先调用.ToList或equiv。我建议不要在.Select之前调用.ToList,正如这里写的那样;这会将所有内容加载到内存中,从而破坏分页的目的。相反,请先执行.Skip和.Take,然后执行.ToList,然后将结果选择为输出格式。@anaximander:必须将其加载到内存中才能使用重载;这就是我所说的不受支持的重载…我知道-我的观点是,如果你要用.ToList或类似的工具将其加载到内存中,那么在你将其压缩到一页后,你应该这样做。我见过很多这样的问题,问为什么使用.Skip和.Take分页没有加快速度,答案是asker在分页之前调用.ToList,这使得它有些冗余。实际上,您可以使用鲜为人知的重载.Select来获取行号,它看起来像这样:.Selectx,I=>new{Index=i,Item=x},这将生成一个对象,其中obj.Index是行号。@anaximander:但该重载没有SQL转换,因此它仅在数据为本地时有效。这意味着如果您有10k条记录,则必须将所有10k条记录都包含在一个可枚举项中,然后才能使用该重载。发生的错误作为对D Stanley ans的注释列出的确如此。但是,如果您使用.Skip和.Take,那么很可能您正在使用它们进行分页,而分页的全部目的是将结果集分解为可管理的块。如果您的页面足够大,以至于将集合加载到内存是一个问题,那么您的分页操作是错误的。