LINQ To SQL Grouping - PullRequest
       16

LINQ To SQL Grouping

2 голосов
/ 27 апреля 2009

Может ли какая-нибудь добрая душа одолжить мне запрос Linq To SQL для следующего запроса 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

Схема базы данных, которую я имею, выглядит следующим образом

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}

ПРИМЕЧАНИЕ: Уловка Convert используется только для отрезания временной части в SignInTime для сравнения

Ответы [ 2 ]

2 голосов
/ 28 апреля 2009

Это определенно вызов. Это некрасиво, но делает свое дело. Он возвращает именно то, что вы ищете. В случае сотрудников без присутствия вы возвращаете имя с нулевым временем.

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", чтобы он возвращал сотрудников с посещаемостью, но вы можете удалить это, если это не то, что вы хотите.

1 голос
/ 28 апреля 2009

Это должно работать:

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)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...