我有一张名为&#34的表格; AttendanceTracker" ...下面是表格的快照
和从此表中检索记录的SQL查询如下
select EmployeeId, Dates, cast(datediff(hour, INTIME, OUTIME) as varchar)+':'+
cast(datediff(minute, INTIME, OUTIME)
- datediff(hour, INTIME, OUTIME) * 60 as varchar)+':'+
cast(datediff(second, INTIME, OUTIME)
- (datediff(minute, INTIME, OUTIME) * 60) as varchar) TotalTime
FROM (
SELECT INN.EmployeeId AS EmployeeId,Convert(DATE,INN.Time,101) AS Dates,MIN(INN.Time) AS INTIME, MAX(OUTT.Time) AS OUTIME
FROM [dbo].[AttendanceTrackers] AS INN,
[dbo].[AttendanceTrackers] AS OUTT
WHERE INN.Type = 'IN' AND
OUTT.Type = 'OUT' AND
INN.EmployeeId = 1 AND
OUTT.EmployeeId = INN.EmployeeId AND
Convert(DATE,INN.Time,101) = Convert(DATE,OUTT.Time,101)
GROUP BY INN.EmployeeId, INN.TenantID, CONVERT(DATE,INN.Time,101)
) X;
查询输出如下
LINQ to实体查询如下
var query = from X in (
(from INN in db.AttendanceTrackers
from OUTT in db.AttendanceTrackers
where
INN.Type == "IN" &&
OUTT.Type == "OUT" &&
INN.EmployeeId == 1 &&
OUTT.EmployeeId == INN.EmployeeId &&
(DateTime)INN.Time == (DateTime)OUTT.Time
group new {INN, OUTT} by new {
INN.EmployeeId,
INN.TenantId,
Column1 = (DateTime?)(DateTime)INN.Time
} into g
select new {
EmployeeId = g.Key.EmployeeId,
Dates = g.Key.Column1,
INTIME = (DateTime?)g.Min(p => p.INN.Time),
OUTIME = (DateTime?)g.Max(p => p.OUTT.Time)
}))
select new {
X.EmployeeId,
X.Dates,
TotalTime = (SqlFunctions.StringConvert((Double)SqlFunctions.DateDiff("hour",X.INTIME,X.OUTIME)) + ":" + SqlFunctions.StringConvert((Double)(SqlFunctions.DateDiff("minute",X.INTIME,X.OUTIME) - SqlFunctions.DateDiff("hour",X.INTIME,X.OUTIME) * 60)) + ":" + SqlFunctions.StringConvert((Double)(SqlFunctions.DateDiff("second",X.INTIME,X.OUTIME) - (SqlFunctions.DateDiff("minute",X.INTIME,X.OUTIME) * 60))))
}
LINQ查询不会返回任何记录......有人可以帮忙吗???
答案 0 :(得分:0)
所以,所以......
首先,您的第一个查询(和linq版本)应该使用连接语法,而不是旧的“带有where子句的笛卡尔积”。这使事情变得更容易理解。
比,你可以使用
EntityFunctions.TruncateTime
将linq中的DateTime的日期部分提供给实体。
然后,我会在执行totalTime
显示部分之前进行枚举,因为它比linq 2实体更容易在linq2对象中执行。 (Datetime2 - DateTime1),它为您提供了一个可以轻松格式化的时间戳。
哪些会做类似的事情(抱歉评论格式化,看起来它不被识别为c#)
var query =
(from inn in db.AttendanceTrackers.Where(m => m.EmployeeId == 1 && m.Type == "IN")
//of course, you could put the where clause on employeeId in another place
join outt in db.AttendanceTrackers.Where(m => m.Type == "OUT")
//join on EmployeeId and Date part of the datetime
on new {
inn.EmployeeId,
time = EntityFunctions.TruncateTime(inn.Time)
} equals new{
outt.EmployeeId,
time = EntityFunctions.TruncateTime(outt.Time)
}
group new{inn,outt}
//group by EmployeeId, TenantId and Date part of the DateTime
by new
{
inn.EmployeeId,
inn.TenantId,
day = EntityFunctions.TruncateTime(Time)
}
into g
//select first inTime and last outTime for the day + employeeId and day
select new
{
employeeId = g.Key.EmployeeId,
day = g.Key.day,
inTime = g.Min(x => x.inn.Time),
outTime = g.Max(x => x.outt.Time)
})
//enumerate, as we filtered all we needed
.ToList()
//easier way to format the desired values.
.Select(x => new
{
x.employeeId,
day = x.day,
TotalTime = (x.outTime - x.inTime).ToString("hh:mm:ss")
});
答案 1 :(得分:0)
如果您已经编写了SQL,那么最好将SQL放在存储过程中并将其映射到实体框架中。您可以将其映射到自定义类型,如linq示例中所示。这样,只有一个代码库可以保持向前,同时它提供相同的功能。
如果您仍想使用linq,那么您可以使用Raphael建议的解决方案,并对服务器使用Sql探查器来确定实体框架生成的sql以及错误所在的位置。