2009-04-27 43 views
2

可以某種靈魂請借給我的LINQ to SQL查詢下面的T-SQL查詢LINQ到SQL分組

SELECT e.EmployeeName, MIN(a.SignInTime), MAX(a.SignOutTime) 
FROM Employee e 
LEFT OUTER JOIN Attendance a ON e.Id = a.EmployeeId AND CAST (CONVERT (varchar, a.SignInTime, 106) AS DATETIME) = '28 APR 2009' 
GROUP BY e.EmployeeName 

數據庫模式,我有如下

Employee: {Id: int identity PK, EmployeeName: varchar(200) NOT NULL} 
Attendance: {Id: int identity PK, EmployeeId: int FK(Employee(Id)) NOT NULL, SignInTime: DateTime, SignOutTime: DateTime} 

注意:轉換噱頭只用於切斷SignInTime中的時間部分進行比較

回答

2

這絕對是一個挑戰。這很醜陋,但它有訣竅。它返回到你正在尋找的東西。如果沒有出席的員工,您會以空時間返回名稱。

var selectedDate = new DateTime(2009,4,28); 
var query = from e in db.Employees 
    join a in db.Attendances on e.Id equals a.EmployeeId into Temp   
    from t in Temp.DefaultIfEmpty() 
    where t.SignInTime == null || (t.SignInTime >= selectedDate && t.SignInTime < selectedDate.AddDays(1)) 
    group t by e.EmployeeName into grouped   
    select new 
    { 
     Employee = grouped.Key, 
     FirstSignInTime = grouped.Min(a => a.SignInTime), 
     LastSignOutTime = grouped.Max(a => a.SignOutTime) 
    }; 

這是由表達發出的SQL:

DECLARE @p0 DateTime = '2009-04-27 00:00:00.000' 
DECLARE @p1 DateTime = '2009-04-28 00:00:00.000' 

SELECT MIN([t1].[SignInTime]) AS [FirstSignInTime], MAX([t1].[SignOutTime]) AS [LastSignOutTime], [t0].[EmployeeName] AS [Employee] 
FROM [Employee] AS [t0] 
LEFT OUTER JOIN [Attendance] AS [t1] ON [t0].[Id] = [t1].[EmployeeId] 
WHERE ([t1].[SignInTime] IS NULL) OR (([t1].[SignInTime] >= @p0) AND ([t1].[SignInTime] < @p1)) 
GROUP BY [t0].[EmployeeName] 

這是非常接近原始的SQL。我添加了「t.SignInTime == null」的地方,以便它返回員工出席,但如果這不是你想要的,你可以刪除它。

+0

@Ali - 我更新了我原來的帖子。請試一試。 – 2009-04-27 22:10:42

1

這應該工作:

from e in db.Employee 
join a in db.Attendance 
     on new { e.Id, Column1 = (DateTime?)Convert.ToDateTime(Convert.ToString(a.SignInTime)) } 
    equals new { Id = a.EmployeeId, Column1 = "28 APR 2009" } into a_join 
from a in a_join.DefaultIfEmpty() 
group new {e, a} by new { 
    e.EmployeeName 
} into g 
select new { 
    g.Key.EmployeeName, 
    Column1 = g.Min(p => p.a.SignInTime), 
    Column2 = g.Max(p => p.a.SignoutTime) 
}