为什么EF不允许在查询生成期间进行转换?

时间:2015-08-29 07:27:11

标签: c# entity-framework

EF(实体帧工作)代码看起来

我的错误:

  

LINQ to Entities无法识别方法' System.String ToString(System.String)'方法,并且此方法无法转换为商店表达式。

我的代码

 public List<AttendanceDisplayModel> GetAttendanceById(string userId)
        {
            TimeSpan StartTime = TimeSpan.Parse("9:00:00");
            TimeSpan EndTime = TimeSpan.Parse("18:00:00");
            return travelContext.Attendances.Where(a => a.UserId == userId).Select(s => new AttendanceDisplayModel()
                  {
                      Id = s.Id,
                      EmployeeNumber = s.EmployeeNumber,
                      Absent = s.Absent,
                      AttendanceDate = s.AttendanceDate,
                      BelowTime = s.BelowTime,
                      CompanyId = s.CompanyId,
                      CompOffId = s.CompanyId,

                      HoliDayId = s.HoliDayId,
                      InTime = s.InTime,
                      OutTime = s.OutTime,
                      ISCompOFF = s.ISCompOFF,
                      Late = TimeSpan.FromMinutes(Convert.ToDouble(EntityFunctions.DiffMinutes(StartTime, s.InTime))).ToString(@"hh\:mm\:ss"),
                      Early = TimeSpan.FromMinutes(Convert.ToDouble(EntityFunctions.DiffMinutes(s.InTime, StartTime))).ToString(@"hh\:mm\:ss"),
                      LeaveId = s.LeaveId,
                      OverTime = s.OverTime,
                      UserId = s.UserId,
                      WeekOff = s.WeekOff,
                      WorkHour = s.WorkHour
                  }).ToList();
        }

错误来自此行

Late = TimeSpan.FromMinutes(Convert.ToDouble(EntityFunctions.DiffMinutes(StartTime, s.InTime))).ToString(@"hh\:mm\:ss"),
                      Early = TimeSpan.FromMinutes(Convert.ToDouble(EntityFunctions.DiffMinutes(s.InTime, StartTime))).ToString(@"hh\:mm\:ss"),

avvv !!实际上我对Cute EF(实体框架)非常生气。因为我无法从EF查询内部转换任何对象,就像我的代码一样。

我看到了来自stackoverflow的Soooo许多解决方案。解决方案只有可以全局声明变量,然后您可以在EF查询中使用它。但是在这种情况下我无法声明任何全局计算变量。这称为EF的原因是WTF代码..

请任何人告诉Entity Framework,接受转换为代码生成期。

  

给我这种情况的解决方案。我需要计算不同的分钟并将其转换为小时,分钟和秒(00:00:00)格式化。

谢谢

3 个答案:

答案 0 :(得分:1)

EF无法将ToString(格式)转换为SQL表达式,您可以做的最好的事情是从数据库中检索时间跨度,然后添加一个非maped属性,它将时间跨度作为字符串返回,如下所示:< / p>

public class AttendanceDisplayModel
{
    //blablabla 
    public TimeSpan Late { get; set; }
    public string LateFormatted{ get{ return Late.ToString(@"hh\:mm\:ss"); } }
}

编辑:修改以完成对这些属性的所有工作:

public class AttendanceDisplayModel
{
    //blablabla 
    public int Late { get; set; }
    public string LateFormatted{ get{ return new TimeSpan((double)Late ).ToString(@"hh\:mm\:ss"); } }
}

并且在您的查询中不再是:

 Late = TimeSpan.FromMinutes(Convert.ToDouble(EntityFunctions.DiffMinutes(StartTime, s.InTime))).ToString(@"hh\:mm\:ss"),

DO

 Late = EntityFunctions.DiffMinutes(StartTime, s.InTime),

修改

现在完整的代码:

public class AttendanceDisplayModel
{
    //The rest of the propertis as you have them
    public int Late { get; set; }
    public string LateFormatted{ get{ return new TimeSpan((double)Late).ToString(@"hh\:mm\:ss"); } }
    public int Early{ get; set; }
    public string EarlyFormatted{ get{ return new TimeSpan((double)Early).ToString(@"hh\:mm\:ss"); } }
}

    public List<AttendanceDisplayModel> GetAttendanceById(string userId)
    {
        TimeSpan StartTime = TimeSpan.Parse("9:00:00");
        TimeSpan EndTime = TimeSpan.Parse("18:00:00");
        return travelContext.Attendances.Where(a => a.UserId == userId).Select(s => new AttendanceDisplayModel()
              {
                  Id = s.Id,
                  EmployeeNumber = s.EmployeeNumber,
                  Absent = s.Absent,
                  AttendanceDate = s.AttendanceDate,
                  BelowTime = s.BelowTime,
                  CompanyId = s.CompanyId,
                  CompOffId = s.CompanyId,

                  HoliDayId = s.HoliDayId,
                  InTime = s.InTime,
                  OutTime = s.OutTime,
                  ISCompOFF = s.ISCompOFF,
                  Late = EntityFunctions.DiffMinutes(StartTime, s.InTime),
                  Early = EntityFunctions.DiffMinutes(s.InTime, StartTime),
                  LeaveId = s.LeaveId,
                  OverTime = s.OverTime,
                  UserId = s.UserId,
                  WeekOff = s.WeekOff,
                  WorkHour = s.WorkHour
              }).ToList();
    }

答案 1 :(得分:1)

在不深入研究类型的情况下,我无法提出比这更好的解决方案,但在使用Select()进行转换之前使用ToList()实现查询应该可以解决问题。它从等式中删除了EF Linq Provider。

return travelContext.Attendances.Where(a => a.UserId == userId).ToList().Select(s => new AttendanceDisplayModel()
              {
                  Id = s.Id,
                  EmployeeNumber = s.EmployeeNumber,
                  Absent = s.Absent,
                  AttendanceDate = s.AttendanceDate,
                  BelowTime = s.BelowTime,
                  CompanyId = s.CompanyId,
                  CompOffId = s.CompanyId,

                  HoliDayId = s.HoliDayId,
                  InTime = s.InTime,
                  OutTime = s.OutTime,
                  ISCompOFF = s.ISCompOFF,
                  Late = TimeSpan.FromMinutes(StartTime - s.InTime).ToString(@"hh\:mm\:ss"),
                  Early = TimeSpan.FromMinutes(s.InTime - StartTime).ToString(@"hh\:mm\:ss"),
                  LeaveId = s.LeaveId,
                  OverTime = s.OverTime,
                  UserId = s.UserId,
                  WeekOff = s.WeekOff,
                  WorkHour = s.WorkHour
              });

转换未检查。我留给你解决这个问题。

答案 2 :(得分:0)

EF不知道如何将任何自定义方法转换为SQL,无论它的框架是什么,除非它特别知道如何操作。 连接可以由各种不同的数据库类型支持,因此即使您在逻辑上知道它可以转换为SQL,也不会支持这种类型的事情。 使用EF检索数据,然后在调用ToList或类似数据后,您就可以在数据已实现为实际数据的情况下调用LINQ和自定义方法。 这偶尔会让我感到困惑,但可以通过对检索到的数据执行lambda,方法或属性来处理,以执行操作。