2012-01-04 10 views
2

に変換したいのですが、LINQではなくSQLを理解しているため、LINQ to Entitiesで排他的に使用していたMS SQLデータベースがあります。私は、より多くのSQLを学び、場合によってはストアドプロシージャを使用して処理速度を上げるというアイデアを思いついています。しかし、私は以下のようにSQLで書く方法がないので、LinqPadが出発点として生成するものを見ています。複雑なLinqクエリをストアドプロシージャ

次のクエリは、特定の「チャンネル」のタイトルが「キューに登録された回数」または過去7日間のチャンネル数に基づいて、そのタイトルの上位3つの「俳優」注文。

var dateStart = DateTime.Now.AddDays(-7); 
var dateNow = DateTime.Now; 
var channels = new[] { 1 }; 

var query = (from p in TitleQueues 
        where p.QueueTime >= dateStart 
          && p.QueueTime <= dateNow 
        group p by p.TitleId 
        into grouped 
        from t in Titles 
        let cast = (from tc in t.TitlePeoples 
        from td in tc.TitlePersonTitlePeopleDepartments 
        where td.Department.Type == "Actors" 
        orderby tc.Order 
        select new { tc.Person.Name, tc.Person.Id }).Take(3) 
        where t.Id == grouped.Key 
        from g in t.TitleSources 
        where 
         channels.Contains(g.TitleProviderId) && g.AvailableFrom <= dateNow && 
         g.AvailableTo >= dateNow 
         && t.Rank != null 
        orderby grouped.Count() descending , t.Rank 
        select new { 
         t.Id, 
         t.Name, 
         t.ReleaseYear, 
         t.ShortSynopsis, 
         t.TitleTypeId, 
         t.MPAARating, 
         t.Runtime, 
         t.IMDbTop250Rank, 
         t.CombinedRating, 
         cast 
        }).Take(10); 

        query.Dump(); 

これは、SQL LinqPadは、上記のLINQクエリに基づいて生成される:

-- Region Parameters 
DECLARE @p0 DateTime2 = '2011-12-28 12:13:29.4306979' 
DECLARE @p1 DateTime2 = '2012-01-04 12:13:29.4306979' 
DECLARE @p2 Int = 1 
DECLARE @p3 DateTime2 = '2012-01-04 12:13:29.4306979' 
DECLARE @p4 DateTime2 = '2012-01-04 12:13:29.4306979' 
-- EndRegion 
SELECT TOP (10) [t2].[Id], [t2].[Name], [t2].[ReleaseYear], [t2].[ShortSynopsis], [t2].[TitleTypeId], [t2].[MPAARating], [t2].[Runtime], [t2].[IMDbTop250Rank], [t2].[CombinedRating] 
FROM (
    SELECT [t0].[TitleId] 
    FROM [TitleQueues] AS [t0] 
    WHERE ([t0].[QueueTime] >= @p0) AND ([t0].[QueueTime] <= @p1) 
    GROUP BY [t0].[TitleId] 
    ) AS [t1] 
CROSS JOIN [Titles] AS [t2] 
CROSS JOIN [TitleSources] AS [t3] 
WHERE ([t3].[TitleProviderId] IN (@p2)) AND ([t3].[AvailableFrom] <= @p3) AND ([t3].[AvailableTo] >= @p4) AND ([t2].[Rank] IS NOT NULL) AND ([t2].[Id] = [t1].[TitleId]) AND ([t3].[TitleId] = [t2].[Id]) 
ORDER BY (
    SELECT COUNT(*) 
    FROM [TitleQueues] AS [t4] 
    WHERE ([t1].[TitleId] = [t4].[TitleId]) AND ([t4].[QueueTime] >= @p0) AND ([t4].[QueueTime] <= @p1) 
    ) DESC, [t2].[Rank] 
GO 

-- Region Parameters 
DECLARE @p0 VarChar(1000) = 'Actors' 
DECLARE @x1 Int = 130323 
-- EndRegion 
SELECT TOP (3) [t3].[Name], [t3].[Id] 
FROM [TitlePeople] AS [t0] 
CROSS JOIN [TitlePeopleDepartments] AS [t1] 
INNER JOIN [Departments] AS [t2] ON [t2].[Id] = [t1].[DepartmentId] 
INNER JOIN [People] AS [t3] ON [t3].[Id] = [t0].[PersonId] 
WHERE ([t2].[Type] = @p0) AND ([t0].[TitleId] = @x1) AND ([t1].[TitlePersonId] = [t0].[Id]) 
ORDER BY [t0].[Order] 
GO 

-- Region Parameters 
DECLARE @p0 VarChar(1000) = 'Actors' 
DECLARE @x1 Int = 127948 
-- EndRegion 
SELECT TOP (3) [t3].[Name], [t3].[Id] 
FROM [TitlePeople] AS [t0] 
CROSS JOIN [TitlePeopleDepartments] AS [t1] 
INNER JOIN [Departments] AS [t2] ON [t2].[Id] = [t1].[DepartmentId] 
INNER JOIN [People] AS [t3] ON [t3].[Id] = [t0].[PersonId] 
WHERE ([t2].[Type] = @p0) AND ([t0].[TitleId] = @x1) AND ([t1].[TitlePersonId] = [t0].[Id]) 
ORDER BY [t0].[Order] 
GO 

-- Region Parameters 
DECLARE @p0 VarChar(1000) = 'Actors' 
DECLARE @x1 Int = 90578 
-- EndRegion 
SELECT TOP (3) [t3].[Name], [t3].[Id] 
FROM [TitlePeople] AS [t0] 
CROSS JOIN [TitlePeopleDepartments] AS [t1] 
INNER JOIN [Departments] AS [t2] ON [t2].[Id] = [t1].[DepartmentId] 
INNER JOIN [People] AS [t3] ON [t3].[Id] = [t0].[PersonId] 
WHERE ([t2].[Type] = @p0) AND ([t0].[TitleId] = @x1) AND ([t1].[TitlePersonId] = [t0].[Id]) 
ORDER BY [t0].[Order] 
GO 

-- Region Parameters 
DECLARE @p0 VarChar(1000) = 'Actors' 
DECLARE @x1 Int = 129887 
-- EndRegion 
SELECT TOP (3) [t3].[Name], [t3].[Id] 
FROM [TitlePeople] AS [t0] 
CROSS JOIN [TitlePeopleDepartments] AS [t1] 
INNER JOIN [Departments] AS [t2] ON [t2].[Id] = [t1].[DepartmentId] 
INNER JOIN [People] AS [t3] ON [t3].[Id] = [t0].[PersonId] 
WHERE ([t2].[Type] = @p0) AND ([t0].[TitleId] = @x1) AND ([t1].[TitlePersonId] = [t0].[Id]) 
ORDER BY [t0].[Order] 
GO 

-- Region Parameters 
DECLARE @p0 VarChar(1000) = 'Actors' 
DECLARE @x1 Int = 130546 
-- EndRegion 
SELECT TOP (3) [t3].[Name], [t3].[Id] 
FROM [TitlePeople] AS [t0] 
CROSS JOIN [TitlePeopleDepartments] AS [t1] 
INNER JOIN [Departments] AS [t2] ON [t2].[Id] = [t1].[DepartmentId] 
INNER JOIN [People] AS [t3] ON [t3].[Id] = [t0].[PersonId] 
WHERE ([t2].[Type] = @p0) AND ([t0].[TitleId] = @x1) AND ([t1].[TitlePersonId] = [t0].[Id]) 
ORDER BY [t0].[Order] 
GO 

-- Region Parameters 
DECLARE @p0 VarChar(1000) = 'Actors' 
DECLARE @x1 Int = 121981 
-- EndRegion 
SELECT TOP (3) [t3].[Name], [t3].[Id] 
FROM [TitlePeople] AS [t0] 
CROSS JOIN [TitlePeopleDepartments] AS [t1] 
INNER JOIN [Departments] AS [t2] ON [t2].[Id] = [t1].[DepartmentId] 
INNER JOIN [People] AS [t3] ON [t3].[Id] = [t0].[PersonId] 
WHERE ([t2].[Type] = @p0) AND ([t0].[TitleId] = @x1) AND ([t1].[TitlePersonId] = [t0].[Id]) 
ORDER BY [t0].[Order] 
GO 

-- Region Parameters 
DECLARE @p0 VarChar(1000) = 'Actors' 
DECLARE @x1 Int = 121957 
-- EndRegion 
SELECT TOP (3) [t3].[Name], [t3].[Id] 
FROM [TitlePeople] AS [t0] 
CROSS JOIN [TitlePeopleDepartments] AS [t1] 
INNER JOIN [Departments] AS [t2] ON [t2].[Id] = [t1].[DepartmentId] 
INNER JOIN [People] AS [t3] ON [t3].[Id] = [t0].[PersonId] 
WHERE ([t2].[Type] = @p0) AND ([t0].[TitleId] = @x1) AND ([t1].[TitlePersonId] = [t0].[Id]) 
ORDER BY [t0].[Order] 
GO 

-- Region Parameters 
DECLARE @p0 VarChar(1000) = 'Actors' 
DECLARE @x1 Int = 125377 
-- EndRegion 
SELECT TOP (3) [t3].[Name], [t3].[Id] 
FROM [TitlePeople] AS [t0] 
CROSS JOIN [TitlePeopleDepartments] AS [t1] 
INNER JOIN [Departments] AS [t2] ON [t2].[Id] = [t1].[DepartmentId] 
INNER JOIN [People] AS [t3] ON [t3].[Id] = [t0].[PersonId] 
WHERE ([t2].[Type] = @p0) AND ([t0].[TitleId] = @x1) AND ([t1].[TitlePersonId] = [t0].[Id]) 
ORDER BY [t0].[Order] 
GO 

-- Region Parameters 
DECLARE @p0 VarChar(1000) = 'Actors' 
DECLARE @x1 Int = 91239 
-- EndRegion 
SELECT TOP (3) [t3].[Name], [t3].[Id] 
FROM [TitlePeople] AS [t0] 
CROSS JOIN [TitlePeopleDepartments] AS [t1] 
INNER JOIN [Departments] AS [t2] ON [t2].[Id] = [t1].[DepartmentId] 
INNER JOIN [People] AS [t3] ON [t3].[Id] = [t0].[PersonId] 
WHERE ([t2].[Type] = @p0) AND ([t0].[TitleId] = @x1) AND ([t1].[TitlePersonId] = [t0].[Id]) 
ORDER BY [t0].[Order] 
GO 

-- Region Parameters 
DECLARE @p0 VarChar(1000) = 'Actors' 
DECLARE @x1 Int = 121903 
-- EndRegion 
SELECT TOP (3) [t3].[Name], [t3].[Id] 
FROM [TitlePeople] AS [t0] 
CROSS JOIN [TitlePeopleDepartments] AS [t1] 
INNER JOIN [Departments] AS [t2] ON [t2].[Id] = [t1].[DepartmentId] 
INNER JOIN [People] AS [t3] ON [t3].[Id] = [t0].[PersonId] 
WHERE ([t2].[Type] = @p0) AND ([t0].[TitleId] = @x1) AND ([t1].[TitlePersonId] = [t0].[Id]) 
ORDER BY [t0].[Order] 

だからこれは、ストアドプロシージャのための良い出発点でしょうか?もしあなたがこれのprocを書くなら、それはどのように見えるでしょうか?

+0

最初の質問:生成されたSQLは、LINQ式と同じ結果を返しますか? –

+0

うわー...それはLINQを理解するのが難しいことの一つです。あなたがLINQを理解して良いこと。 LINQではなく、SQLを理解している人を想像してみてください。どれくらいのトラブルがありますか?とにかく、あなたの質問に基づいて、クエリは異なる結果を返しますか?私はあなたの "OR"タイル.. ORチャンネルを参照します。そうですか? – Schultz9999

+0

@BobKaufmanはい、両方のクエリが同じ結果を返します。 – Jeff

答えて

0

可能であれば、SQLプロファイラを使用して実際のSQLがデータベースに送信されていることを確認してください。 これはおそらくより良い出発点を提供します。

+0

私はそれをしましたが、LinqPadから生成されたSQLはEFから送信されたものよりもずっと読みやすく、読みやすくなっています。 – Jeff