1

asp.net アプリケーションで LINQ から SQL に呼び出したい 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 の回答は問題を解決しますが、2 つのクエリの実行計画を見ると、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 に答える