LINQ

2009-04-27 13 views
2

はいくつかの種類の魂はLINQ

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} 

NOTEを次のように私が持っているデータベーススキーマがあり、次のT-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 

のためのSQLクエリに私のLINQを貸してくださいすることができ: Convertギミックは、比較のために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 - 元の投稿を更新しました。試してみてください。 –

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