2009-04-27 9 views
2

une bonne âme peut s'il vous plaît me prêter la requête LINQ to SQL pour le T-SQL QueryLINQ to SQL Groupement

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 

suivant Le schéma de base de données que j'ai est la suivante

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 : Le gimmick Convert est utilisé uniquement pour couper la partie de temps dans le SignInTime pour la comparaison

Répondre

2

Ceci est certainement un défi. C'est moche, mais ça fait l'affaire. Il retourne exactement ce que vous cherchez. Dans le cas des employés sans présence, vous récupérez le nom avec des temps nuls.

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

C'est le SQL qui est émise par cette expression:

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] 

Ceci est très proche de votre SQL d'origine. J'ai ajouté où "t.SignInTime == null" afin qu'il renvoie les employés avec présence, mais vous pouvez supprimer cela si ce n'est pas ce que vous voulez.

+0

@Ali - J'ai mis à jour mon message original. S'il vous plaît essayer. –

1

Cela devrait fonctionner:

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