简体   繁体   English

Linq到SQL | 按日期排列的前5个不同订单

[英]Linq to SQL | Top 5 Distinct Order by Date

I have an SQL query which I want to call from LINQ to SQL in asp.net application. 我有一个SQL查询,我想从LINQ调用asp.net应用程序中的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 

I don't know whether its possible or not through linq to sql, if not then please provide any other way around. 我不知道是否可以通过linq to sql,如果不能,请提供其他方法。

I think you'd have to change the SQL partition to a Linq group-by. 我认为您必须将SQL分区更改为Linq group-by。 (Effectively all the partition does is group by song, and select the newest row for each group.) So something like this: (实际上,所有分区所做的都是按歌曲分组,并为每个分组选择最新的行。)因此,如下所示:

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);

Although McGarnagle answer solves the problem, but when i see the execution plan for the two queries, it was really amazing to see that linq to sql was really too slow as compare to native sql queries. 尽管McGarnagle的答案解决了问题,但是当我看到两个查询的执行计划时,与本地sql查询相比,看到linq to sql确实太慢了,真是太神奇了。 See the generated query for the above linq to 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 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM