LINQ to SQL - Saat başına gruplandırma


11

Sütun türünün DateTime olduğunu düşünürsek bir LINQ sonucunu saatlerce SQL sorgusuna nasıl gruplandırabilirim?

23

Teknik saatler için bir çözüm (bağlam-az). Bu üretir

var query = myDC.Orders 
    .GroupBy(x => x.OrderDate.Hour) 
    .Select(g => new { 
     Hour = g.Key, 
     Amount = g.Sum(x => x.OrderAmount) 
    }); 

:

SELECT SUM([t1].[OrderAmount]) AS [Amount], [t1].[value] AS [Hour] 
FROM (
    SELECT DATEPART(Hour, [t0].[OrderDate]) AS [value], [t0].[OrderAmount] 
    FROM [dbo].[Orders] AS [t0] 
    ) AS [t1] 
GROUP BY [t1].[value] 

İşte iş saatleri (bağlam-ful) için bir çözümdür. Bu üretir

DateTime zeroDate = new DateTime(2008, 1, 1); 

var query = myDC.Orders 
    .GroupBy(x => System.Data.Linq.SqlClient.SqlMethods.DateDiffHour(zeroDate, x.OrderDate) 
    ) 
    .Select(g => new { Hours = g.Key, Amount = g.Sum(x => x.OrderAmount) }) 
    .Select(x => new { Hour = zeroDate.AddHours(x.Hours), Amount = x.Amount}); 

:

SELECT DATEADD(ms, (CONVERT(BigInt,(CONVERT(Float,[t2].[value2])) * 3600000)) % 86400000, DATEADD(day, (CONVERT(BigInt,(CONVERT(Float,[t2].[value2])) * 3600000))/86400000, @p1)) AS [Hour], [t2].[value] AS [Amount] 
FROM (
    SELECT SUM([t1].[OrderAmount]) AS [value], [t1].[value] AS [value2] 
    FROM (
     SELECT DATEDIFF(Hour, @p0, [t0].[OrderDate]) AS [value], [t0].[OrderAmount] 
     FROM [dbo].[Orders] AS [t0] 
     ) AS [t1] 
    GROUP BY [t1].[value] 
    ) AS [t2] 

Ugh - o Bigint/şamandıra/malzeme çirkin ve doğrulamak zor milisaniye. Bu üretir

var results = myDC.Orders 
    .GroupBy(x => System.Data.Linq.SqlClient.SqlMethods.DateDiffHour(zeroDate, x.OrderDate) 
    ) 
    .Select(g => new { Hours = g.Key, Amount = g.Sum(x => x.OrderAmount) }) 
    .ToList() 
    .Select(x => new { Hour = zeroDate.AddHours(x.Hours), Amount = x.Amount}); 

: Ben istemci tarafında geri eklenmesini yapmayı tercih ederim burada

SELECT SUM([t1].[OrderAmount]) AS [Amount], [t1].[value] AS [Hours] 
FROM (
    SELECT DATEDIFF(Hour, @p0, [t0].[OrderDate]) AS [value], [t0].[OrderAmount] 
    FROM [dbo].[Orders] AS [t0] 
    ) AS [t1] 
GROUP BY [t1].[value] 

Ve contextful saat yapmanın üçüncü yoldur. Bu çok C# dostça, ancak veritabanında string mantığı var (yuck).

SELECT SUM([t1].[OrderAmount]) AS [Amount], [t1].[value] AS [Hour] 
FROM (
    SELECT CONVERT(DATETIME, (CONVERT(NCHAR(4), DATEPART(Year, [t0].[OrderDate])) + ('-' + (CONVERT(NCHAR(2), DATEPART(Month, [t0].[OrderDate])) + ('-' + CONVERT(NCHAR(2), DATEPART(Day, [t0].[OrderDate])))))) + (' ' + (CONVERT(NCHAR(2), DATEPART(Hour, [t0].[OrderDate])) + (':' + (CONVERT(NCHAR(2), @p0) + (':' + CONVERT(NCHAR(2), @p1)))))), 120) AS [value], [t0].[OrderAmount] 
    FROM [dbo].[Orders] AS [t0] 
    ) AS [t1] 
GROUP BY [t1].[value] 
üretir

var query = myDC.Orders 
    .GroupBy(x => new DateTime(x.OrderDate.Year, x.OrderDate.Month, x.OrderDate.Day, x.OrderDate.Hour, 0, 0)) 
    .Select(g => new { Hour = g.Key, Amount = g.Sum(x => x.OrderAmount) });