sql server查询到Linq到实体转换不检索记录

时间:2014-07-16 07:10:27

标签: linq-to-entities

我有一张名为&#34的表格; AttendanceTracker" ...下面是表格的快照

enter image description here

和从此表中检索记录的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;

查询输出如下

enter image description here

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查询不会返回任何记录......有人可以帮忙吗???

2 个答案:

答案 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以及错误所在的位置。