LINQ lambda - OrderByDescending正在添加不需要的选择

时间:2016-10-10 20:32:54

标签: c# sql-server linq lambda sql-order-by

我正在处理一个非常狂野的lambda查询。这是我最初的LINQ lambda语句(没有按顺序排序/排序):

var query = orders.Join(customers, o => o.CustomerID, c => c.ID, (o, c) => new { o, c })
                .Join(ordersections, o => o.o.ID, os => os.OrderID, (o, os) => new { o.o, o.c, os })
                .Join(tickets, o => o.os.ID, t => t.OrderSectionID, (o, t) => new { o.o, o.c, o.os, t })
                .Join(events, o => o.t.EventID, e => e.id, (o, e) => new { o.o, o.c, o.os, o.t, e })
                .Join(clients, o => o.e.ClientID, cl => cl.id, (o, cl) => new { o.o, o.c, o.os, o.t, o.e, cl })
                .Join(venues, o => o.e.VenueID, v => v.VenueID, (o, v) => new ModelsCs.LINQ.CustomerSearchResult { order = o.o, customer = o.c, orderSection = o.os, ticket = o.t, evt = o.e, client = o.cl, venue = v })
                         .AsExpandable()
                         .Where(predicate) // from PredicateBuilder
                         .GroupBy(x => new
                         {
                             // variables to group by

                         })                         
                         .Select(s => new CustomerSearchResult
                         {
                             // Selecting the variables, all good and fun!
                         });

生成的SQL如下:

SELECT <correct variables to select> 
FROM [dbo].[Order] AS [t0]
INNER JOIN [dbo].[Customer] AS [t1] ON [t0].[Customer] = ([t1].[Customer])
INNER JOIN [dbo].[OrderSection] AS [t2] ON [t0].[Order] = [t2].[Order]
INNER JOIN [dbo].[Ticket] AS [t3] ON [t2].[OrderSection] = [t3].[OrderSection]
INNER JOIN [dbo].[Event] AS [t4] ON [t3].[Event] = [t4].[Event]
INNER JOIN [dbo].[Client] AS [t5] ON [t4].[Client] = ([t5].[Client])
INNER JOIN [dbo].[Venue] AS [t6] ON [t4].[Venue] = ([t6].[Venue])
WHERE ([t5].[Brand] = @p0)
    AND ([t0].[Brand] = @p1)
    AND ([t4].[EventStart] >= @p2)
    AND ([t0].[OrderDateTime] >= @p3)
    AND ([t1].[email] LIKE @p4)
GROUP BY <correct group by variables>

美丽! 但我需要订购结果,所以我最后也想要这个:

...
ORDER BY SortingVariable1 desc

(^^^^这就是我要做的事情)

以下是我已经尝试过的内容:

所以我尝试将它添加到我的LINQ lambda语句中:

.OrderByDescending(x => x.SortingVariable1)

但现在这是生成的SQL代码:

SELECT <correct variables to select>
FROM (
    SELECT <correct GROUP BY variables>
    FROM [dbo].[Order] AS [t0]
    INNER JOIN [dbo].[Customer] AS [t1] ON [t0].[Customer] = ([t1].[Customer])
    INNER JOIN [dbo].[OrderSection] AS [t2] ON [t0].[Order] = [t2].[Order]
    INNER JOIN [dbo].[Ticket] AS [t3] ON [t2].[OrderSection] = [t3].[OrderSection]
    INNER JOIN [dbo].[Event] AS [t4] ON [t3].[Event] = [t4].[Event]
    INNER JOIN [dbo].[Client] AS [t5] ON [t4].[Client] = ([t5].[Client])
    INNER JOIN [dbo].[Venue] AS [t6] ON [t4].[Venue] = ([t6].[Venue])
    WHERE ([t5].[Brand] = @p0)
        AND ([t0].[Brand] = @p1)
        AND ([t4].[EventStart] >= @p2)
        AND ([t0].[OrderDateTime] >= @p3)
        AND ([t1].[email] LIKE @p4)
    GROUP BY <correct group by variables>
    ) AS [t7]
ORDER BY [t7].[SortingVariable1] DESC

无论我在lambda声明的哪个位置放置.OrderByDescending,它都无法正常工作。

我的问题:有没有人知道如何将我的LINQ Lambda语句改为正确在生成的SQL语句的末尾添加ORDER BY SortingVariable1 DESC

2 个答案:

答案 0 :(得分:2)

外部SELECT本身不是问题,因为它没有额外的可识别幅度的开销。添加嵌套允许SQL生成器对任何返回的字段进行排序,甚至是计算出的字段,而不包括计算两次。

此行为是由于以下示例所示的SQL限制:

SELECT A+B as A_plus_B
FROM MyTable
ORDER BY A_plus_B -- <=== This does not work

必须重复上述查询,重复计算两次,即

SELECT A+B as A_plus_B
FROM MyTable
ORDER BY A+B -- <=== Computation is repeated

或使用嵌套查询或CTE:

SELECT A_plusB FROM (
    SELECT A+B as A_plus_B
    FROM MyTable
)
ORDER BY A_plus_B -- <=== This works

LINQ的SQL生成器采用第二种方法,生成您看到的语句。

答案 1 :(得分:-1)

正确添加Order By。它具有自动生成代码的性质,它通常不会像人类生成的代码一样漂亮。它写的内容通常更冗长,只是因为生成这样的代码通常更容易。

如果您希望完全一组SQL代码,则需要手动编写。如果你想让它自动为你生成,那么你将不得不满足于不太漂亮但完全正确且功能相同的代码。