LINQ to SQL 模拟实现 ROW_NUMBER() OVER(ORDER BY ...) 的功能

Posted Abeam

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LINQ to SQL 模拟实现 ROW_NUMBER() OVER(ORDER BY ...) 的功能相关的知识,希望对你有一定的参考价值。

Ø  前言

本来是想使用 LINQ 实现类似 SQL: ROW_NUMBER() OVER(ORDER BY …) 的功能,但是貌似 LINQ 不支持,反正没找到解决办法,无奈使用了LINQ Select() 方法实现。

 

1)   需求,需要实现一下 SQL:

SELECT TOP 10 ROW_NUMBER() OVER(ORDER BY T.TotalMoney DESC) AS SN, * FROM

(

    SELECT T2.Name, SUM(T2.Amount) AS TotalAmount, SUM(T2.TotalMoney) AS TotalMoney FROM Orders AS T1

    LEFT JOIN OrderDetail AS T2 ON(T2.OrderId = T1.Id)

    WHERE 1=1

    AND T1.SalesUserId = 105

    AND T1.PayStatusId = 2

    AND (T1.OrderStatusId >=2 AND T1.OrderStatusId <= 8)

    GROUP BY T2.Name

) AS T

 

2)   使用 LINQ Select() 方法

var result = (from t1 in DataContext.Orders

              join t2 in DataContext.OrderDetail on t1.Id equals t2.OrderId into temp1

              from t12 in temp1.DefaultIfEmpty()

              where t1.SalesUserId == salesUserId && t1.PayStatusId == (int)OrderPayStates.Paid

                  && (t1.OrderStatusId >= (int)OrderStates.Undelivered

                  && t1.OrderStatusId <= (int)OrderStates.ReturnComplete)

              group t12 by t12.Name into group1

              select new

              {

                  Name = group1.Key,

                  TotalAmount = group1.Sum(o => o.Amount),

                  TotalMoney = group1.Sum(o => o.TotalMoney)

              }).OrderByDescending(o => o.TotalMoney).Take(10).AsEnumerable()

              .Select((obj, index) => new

              {

                  Name = obj.Name,

                  TotalAmount = obj.TotalMoney,

                  TotalMoney = obj.TotalMoney,

                  SN = index + 1

              }).ToList();

l  注意:必须加上 AsEnumerable() 方法,且 AsEnumerable() Select() 方法都为延迟查询方法。

 

3)   生成SQL:

exec sp_executesql N\'SELECT TOP (10)

    [Project1].[C3] AS [C1],

    [Project1].[Name] AS [Name],

    [Project1].[C1] AS [C2],

    [Project1].[C2] AS [C3]

    FROM ( SELECT

        [GroupBy1].[A1] AS [C1],

        [GroupBy1].[A2] AS [C2],

        1 AS [C3],

        [GroupBy1].[K1] AS [Name]

        FROM ( SELECT

            [Extent2].[Name] AS [K1],

            SUM([Extent2].[Amount]) AS [A1],

            SUM([Extent2].[TotalMoney]) AS [A2]

            FROM  [dbo].[Orders] AS [Extent1]

            LEFT OUTER JOIN [dbo].[OrderDetail] AS [Extent2] ON [Extent1].[Id] = [Extent2].[OrderId]

            WHERE ([Extent1].[SalesUserId] = @p__linq__0) AND (2 = [Extent1].[PayStatusId]) AND ([Extent1].[OrderStatusId] >= 2) AND ([Extent1].[OrderStatusId] <= 8)

            GROUP BY [Extent2].[Name]

        )  AS [GroupBy1]

    )  AS [Project1]

ORDER BY [Project1].[C2] DESC\',N\'@p__linq__0 bigint\',@p__linq__0=105

 

4)   最终结果(这是我想要的)

LINQ to SQL 实现 GROUP BY聚合ORDER BY

实现接口的 LINQ to SQL 类

本地序列不能在查询运算符的 LINQ to SQL 实现中使用,但 Contains() 运算符除外

数据访问层 - LINQ-To-SQL 和泛型。我可以优化这个吗?

linq to sql 如何返回两个日期的天数差值

SQL to LINQ - 案例语句