1

我有一个 SQL 查询,我想在 asp.net 应用程序中从 LINQ 调用它到 SQL。

SELECT TOP 5 *
FROM   (SELECT SongId,
               DateInserted,
               ROW_NUMBER()
                 OVER(
                   PARTITION BY SongId
                   ORDER BY DateInserted DESC) rn
        FROM   DownloadHistory) t
WHERE  t.rn = 1
ORDER  BY DateInserted DESC 

我不知道它是否可能通过linq to sql,如果没有,请提供任何其他方式。

4

2 回答 2

5

我认为您必须将 SQL 分区更改为 Linq group-by。(实际上所有分区都是按歌曲分组,并为每个组选择最新的行。)所以是这样的:

IEnumerable<DownloadHistory> top5Results = DownloadHistory
    // group by SongId
    .GroupBy(row => row.SongId)

    // for each group, select the newest row
    .Select(grp => 
        grp.OrderByDescending(historyItem => historyItem.DateInserted)
        .FirstOrDefault()
    )

    // get the newest 5 from the results of the newest-1-per-song partition
    .OrderByDescending(historyItem => historyItem.DateInserted)
    .Take(5);
于 2013-07-14T19:59:24.867 回答
0

虽然 McGarnagle 的回答解决了这个问题,但是当我看到这两个查询的执行计划时,看到 linq to sql 与原生 sql 查询相比真的太慢了​​,真是令人惊讶。请参阅为上述 linq to sql 生成的查询:

--It took 99% of the two execution

SELECT TOP (5) [t3].[SongId], [t3].[DateInserted]
    FROM (
        SELECT [t0].[SongId]
        FROM [dbo].[DownloadHistory] AS [t0]
        GROUP BY [t0].[SongId]
        ) AS [t1]
    OUTER APPLY (
        SELECT TOP (1) [t2].[SongId], [t2].[DateInserted]
        FROM [dbo].[DownloadHistory] AS [t2]
        WHERE [t1].[SongId] = [t2].[SongId]
        ORDER BY [t2].[DateInserted] DESC
        ) AS [t3]
    ORDER BY [t3].[DateInserted] DESC


--It took 1% of the two execution
SELECT TOP 5 t.SongId,t.DateInserted
    FROM   (SELECT SongId,
               DateInserted,
               ROW_NUMBER()
                 OVER(
                   PARTITION BY SongId
                   ORDER BY DateInserted DESC) rn
        FROM   DownloadHistory) t
    WHERE  t.rn = 1
    ORDER  BY DateInserted DESC 
于 2013-07-14T20:25:44.460 回答