将SQL Rank()转换为LINQ,或替代

Ref*_*din 13 c# sql linq linq-to-sql

我有下面的SQL语句,可以按预期/期望工作.但是我想将它翻译成LINQ语句(Lambda ??),以便它适合我的其余DAL.但是我无法弄清楚如何在LINQ中模拟Rank().

我在这里发布它的原因,可能是错误的,是看看是否有人有一个替代Rank()声明,以便我可以切换.或者,如果有一种方法Rank()在LINQ中表示也将被欣赏.

USE CMO

SELECT      vp.[PersonID] AS [PersonId]
            ,ce.[EnrollmentID]
            ,vp.[FirstName]
            ,vp.[LastName]
            ,ce.[EnrollmentDate]
            ,ce.[DisenrollmentDate]
            ,wh.WorkerCategory

FROM  [dbo].[vwPersonInfo] AS vp
            INNER JOIN 
            (
                  [dbo].[tblCMOEnrollment] AS ce
                  LEFT OUTER JOIN
                        (
                              SELECT   *
                                          ,RANK()OVER(PARTITION BY EnrollmentID ORDER BY CASE WHEN EndDate IS NULL THEN 1 ELSE 2 END, EndDate DESC, StartDate DESC) AS whrank 
                              FROM  [dbo].[tblWorkerHistory]
                              WHERE WorkerCategory = 2
                        ) AS wh 
                              ON ce.[EnrollmentID] = wh.[EnrollmentID] AND wh.whrank = 1
            ) 
                  ON vp.[PersonID] = ce.[ClientID]

WHERE (vp.LastName NOT IN ('Client','Orientation','Real','Training','Matrix','Second','Not'))
AND (
            (wh.[EndDate] <= GETDATE())
            OR wh.WorkerCategory IS NULL
      ) 
AND (
            (ce.[DisenrollmentDate] IS NULL) 
            OR (ce.[DisenrollmentDate] >= GetDate())
      )
Run Code Online (Sandbox Code Playgroud)

Tot*_*ero 13

这是一个示例,展示了如何在Linq中模拟Rank():

   var q = from s in class.student
                 orderby s.Age descending
                 select new { 
                     Name = s.name, 
                     Rank = (from o in class.student
                             where o.mark > s.mark
                             select o).Count() + 1 
                 };
Run Code Online (Sandbox Code Playgroud)

  • 就我的测试而言,似乎我在外部查询中为每个结果创建一个单独的查询.即使是几千个结果也会出现问题,因此这种方法似乎有限. (4认同)
  • 对我而言,这感觉就像E = mc ^ 2 ..对于一个相对复杂的问题,这是一个非常简单的解决方案 (2认同)
  • 我喜欢你对这个解决方案的想法!我从没想过要那样看.做得好!我最终使用lamda实现,但基于相同的概念:var rankingData = data.Select(s => new {Ranking = data.Count(x => x.Value> s.Value)+1,Name = s.Key ,分数= s.Value}); (2认同)

And*_*bel 8

LINQ内置了级别功能,但查询语法中没有.当使用方法语法时,大多数linq函数有两个版本 - 正常的和一个提供的等级.

一个简单的示例,仅选择每个其他学生,然后将结果序列中的索引添加到结果中:

var q = class.student.OrderBy(s => s.studentId).Where((s, i) => i % 2 == 0)
.Select((s,i) => new
{
  Name = s.Name,
  Rank = i
}
Run Code Online (Sandbox Code Playgroud)

  • 这不是严格的物化列表,还是实际生成与排名相对应的SQL? (3认同)
  • 当我尝试使用它时,我不断收到消息"LINQ无法识别方法......",直到我删除where子句.它似乎不喜欢括号中的2个参数. (2认同)
  • 请注意,这不会处理关系。如果两个项目具有相同的度量,则它们将被赋予不同的排名。 (2认同)