Linq到sql日期时间问题

本文关键字:时间 问题 日期 sql Linq | 更新日期: 2023-09-27 17:57:27

当我调用GetClosestStartDate时,会弹出以下消息附加信息:

LINQ to Entities无法识别方法"System.String"ToString()方法,而此方法无法转换为存储表示我还尝试从"TT.Startdate.Value.ToString()"中删除ToString,并将"string CStartdate{get;set;}更改为DateTime CStartdate{get;set;}"

class Class_CourseStartdate
{
    public string CStartdate { get; set; }
    public int TimeTableID { get; set; }
}
   public List<Class_CourseStartdate> GetClosestStartDate(DateTime CoeStartdate)
   {
       return (from TT in _er.TimeTables
               where TT.Startdate == CoeStartdate
               select new Class_CourseStartdate 
               { CStartdate = TT.Startdate.Value.ToString() ,
                 TimeTableID = TT.TimeTableID 
               }
               ).ToList();
   }

Linq到sql日期时间问题

最简单的方法是在转换为SQL的部分中只获取所需的数据,然后在本地执行其余操作:

public List<Class_CourseStartdate> GetClosestStartDate(DateTime coeStartdate)
{
    return _er.TimeTables
              .Where(tt => tt.Startdate == coeStartdate)
              .Select(tt => new { tt.Startdate, tt.TimeTableID })
              .AsEnumerable() // Do the rest locally
              .Select(tt => new Class_CourseStartdate 
              { 
                   CStartdate = tt.Startdate.Value.ToString() ,
                   TimeTableID = tt.TimeTableID 
              }
              .ToList();
}

请注意,我在这里已经停止使用查询表达式,因为当您需要调用它上的方法时,它会变得很难看——您所做的只是一个简单的WhereSelect。查询表达式在涉及透明标识符时最有用,例如在联接中。

接下来,我会注意到,我们已经在检查tt.Startdate是否等于我们传入的日期——那么为什么要麻烦取它呢?

public List<Class_CourseStartdate> GetClosestStartDate(DateTime coeStartdate)
{
    return _er.TimeTables
              .Where(tt => tt.Startdate == coeStartdate)
              .Select(tt => tt.TimeTableID)
              .AsEnumerable() // Do the rest locally
              .Select(tid => new Class_CourseStartdate 
              { 
                   CStartdate = coeStartDate.ToString() ,
                   TimeTableID = tid
              }
              .ToList();
}

或者可能只是更改方法以返回时间表ID,因为这是真正的。我也会更改方法名称:

public List<int> GetTimeTableIdsForStartDate(DateTime coeStartdate)
{
    return _er.TimeTables
              .Where(tt => tt.Startdate == coeStartdate)
              .Select(tt => tt.TimeTableID)
              .ToList();
}

即使您坚持使用Class_CourseStartdate,我也会将CStartdate属性更改为DateTime而不是string-避免在模型中使用字符串,除非您真的非常必须这样做。

此外,您的命名目前感觉到处都是——Startdate应该到处都是StartDate,您应该去掉CClass_前缀等。

试试这个:

return (from TT in _er.TimeTables
        where TT.Startdate == CoeStartdate
        select new  
        {
            CStartdate = TT.Startdate.Value.ToString() ,
            TimeTableID = TT.TimeTableID 
        }
        ).AsEnumerable()
         .Select(x=> new Class_CourseStartdate
         {
             CStartdate = x.CStartdate.Value.ToString(),
             TimeTableID = x.TimeTableID
         }).ToLIst();

通过这种方式,您可以从数据库中提取数据,然后应用所需的格式。

大多数未在LINQ命名空间中定义的函数不能在IQueryabeLINQ表达式中使用(ToString就是其中之一)。解决方案是直接复制值,然后执行转换,或者用for循环替换LINQ来迭代值,在这种情况下,可以正确使用ToString

首先,您可能有一个异常:TT.StartDate可能为null,当调用Value时,您将得到一个异常。

其次,为什么CStartDate是一个字符串?您将无法使用它执行特定于DateTime的操作,并且如果在具有不同区域性的线程上进行转换,则在将字符串转换回DateTime时可能会遇到问题。

快速修复方法是,在将数据加载到内存后,可以尝试向查询添加第二个投影:

return _er.TimeTables
    .Where(tt => tt.Startdate == CoeStartdate)
    .Select(tt => new { StartDate = tt.StartDate, Id = tt.TimeTableID})
    .ToList()
    .Select(tt => new Class_CourseStartDate
    {
        // Avoid the exception by checking if property has value
        CStartDate = tt.StartDate.HasValue ? tt.StartDate.Value.ToString() : String.Empty,
        TimeTableId = tt.Id
    })
    .ToList();