Linq to sql LINQ到SQL分组

Linq to sql LINQ到SQL分组,linq-to-sql,tsql,Linq To Sql,Tsql,能不能请一些善良的灵魂为下面的T-SQL查询借给我LINQtoSQL查询 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

能不能请一些善良的灵魂为下面的T-SQL查询借给我LINQtoSQL查询

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}
注意:转换技巧仅用于切掉符号时间中的时间部分进行比较

这应该可以:

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

这绝对是一个挑战。它很难看,但它确实起了作用。它返回的正是您要查找的内容。如果员工未出席,则返回的姓名时间为空

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)
    };
var selectedDate=新日期时间(2009,4,28);
var query=来自数据库中的e.Employees
将a加入db。e.Id上的出席人数等于a.EmployeeId加入Temp
来自临时DefaultIfEmpty()中的t
其中t.signetime==null | |(t.signetime>=selectedDate&&t.signetimea.SigningTime),
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]
DECLARE@p0 DateTime='2009-04-27 00:00:00.000'
声明@p1 DateTime='2009-04-28 00:00:00.000'
选择MIN([t1].[SigningTime])作为[FirstSigningTime],选择MAX([t1].[SignOutTime])作为[LastSignOutTime],选择[t0].[EmployeeName]作为[Employee]
从[雇员]起,作为[t0]
在[t0].[Id]=[t1].[EmployeeId]上以[t1]的身份离开外部加入[Attention]
其中([t1].[SigningTime]为空)或([t1].[SigningTime]>=@p0)和([t1].[SigningTime]<@p1))
分组依据[t0]。[EmployeeName]
这与原始SQL非常接近。我在其中添加了“t.SignInTime==null”,这样它会返回有出勤率的员工,但如果这不是您想要的,您可以将其删除