代码之家  ›  专栏  ›  技术社区  ›  Mark Brittingham

使用Linq for ObjectDataSource:如何使用ToSortTimeString转换日期时间?

  •  1
  • Mark Brittingham  · 技术社区  · 17 年前

    我正在使用ObjectDataSource访问一个业务类,并试图生成对用户有意义的输出。返回值描述一个类(如在课堂和教学中,而不是在软件中)。我想以这样的范围显示课堂时间:“上午9:00-上午10:00”。

    return classQuery.Select(p => new SelectClassData
                                  {
                                       ClassID = p.ClassID,
                                       Title = p.Title,
                                       StartDate = p.StartDate.ToShortDateString(),
                                       EndDate = p.EndDate.ToShortDateString(),
                                       TimeOfClass =
                                       p.StartDate.ToShortTimeString() + " - " +
                                                           p.EndDate.ToShortTimeString()
                                   }).ToList();
    

    如您所见,我在开始日期和结束日期中对开始时间和结束时间进行编码,即使它们可能在不同的日期。

    当我执行此代码时,我得到:

    “无法将表达式'p.EndDate.ToShortTimeString()'转换为SQL,并且无法将其视为本地表达式。”

    我知道我正在预测结果,但作为Linq的新手,我假设对ToSortTimeString的C#调用发生在预测之后。有人能帮我弄清楚我要找的绳子是怎么来的吗?

    2 回复  |  直到 17 年前
        1
  •  5
  •   Mehrdad Afshari    17 年前

    原因是查询正在LINQ to SQL中使用。LINQtoSQL将查询视为表达式树。它为某些方法定义了映射(例如, Contains )但由于它并没有真正执行它们,所以它不能在任意方法上工作。它解析查询并将其提交给SQL server。等价的查询将作为SQL语句在数据库服务器上执行,结果将返回。问题是 ToShortTimeString() 在LINQ中没有等效的SQL转换为SQL。这里使用的技巧是从SQL server获取数据并在客户端调用该方法( AsEnumerable 我会这样做)。

    return classQuery.Select(p => new { p.ClassID, p.Title, p.StartDate, p.EndDate })
       .AsEnumerable()
       .Select(p => new SelectClassData { 
           ClassID = p.ClassID, 
           Title = p.Title, 
           StartDate = p.StartDate.ToShortDateString(), 
           EndDate = p.EndDate.ToShortDateString(), 
           TimeOfClass = p.StartDate.ToShortTimeString() + " - " + p.EndDate.ToShortTimeString() })
       .ToList();
    
        2
  •  0
  •   Mark Brittingham    17 年前

    我很喜欢Mehrdad的回答。它不仅解决了这个问题,还教会了我一些关于Linq的知识。非常感谢。

    不过,我一直对这个问题喋喋不休,并提出了一种不同的方法,我将在这里描述,以防其他人绊倒在这个问题上。我的Linq到SQL代码现在显示:

    return classQuery.Select(p => new SelectClassData
                                  {
                                       ClassID = p.ClassID,
                                       Title = p.Title,
                                       sDate = p.StartDate,
                                       eDate = p.EndDate
                                  }).ToList();
    

    请注意,sDate和eDate现在是DateTime对象,而不是字符串。在“SelectClassData”对象中,我只是更改了声明,以便通过属性getter访问StartDate、EndDate和TimeOfClass变量:

    public class SelectClassData
    {
        public int ClassID { get; set; }
        public string Title { get; set; }
        public DateTime sDate { get; set; }
        public DateTime eDate { get; set; }
        public string StartDate { get { return GetSDate(); } }
        public string EndDate { get { return GetEDate(); } }
        public string TimeOfClass { get { return GetTimeOfClass(); } }
    
        protected string GetSDate()
        {
            return sDate.ToShortDateString();
        }
    
        protected string GetEDate()
        {
            return eDate.ToShortDateString();
        }
    
        protected string GetTimeOfClass()
        {
            return sDate.ToShortTimeString() + " - " + eDate.ToShortTimeString();
        }
    }
    

    也就是说,我通过LinqToSql设置了sDate和eDate,但进行了“ToShortTimeString”和“ToShortDateString”转换 之后