2

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

这是我用来提取数据的 Linq 查询:

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 的新手,我假设 C# 调用 ToShortTimeString 发生在投影之后。谁能帮我弄清楚如何获得我正在寻找的字符串?

4

2 回答 2

5

原因是查询正在 LINQ to SQL 中使用。LINQ to SQL 将查询视为表达式树。它为某些方法(例如Contains)定义了映射,但由于它并没有真正执行它们,因此它不能在任意方法上工作。它解析查询并将其提交给 SQL 服务器。查询的等价物将作为 SQL 语句在数据库服务器上执行,并返回结果。问题是ToShortTimeString()在 LINQ to SQL 中没有等效的 SQL 转换。这里使用的技巧是从 SQL 服务器获取数据并在客户端调用方法(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();
于 2009-01-15T23:24:02.590 回答
0

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

不过,我一直在努力解决这个问题,并且确实提出了一种不同的方法,我将在这里描述,以防其他人在这个问题上绊倒想要考虑。我的 Linq to SQL 代码现在显示为:

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

请注意,sDate 和 eDate 现在是 DateTime 对象而不是字符串。在“SelectClassData”对象中,我只是更改了声明,以便通过属性获取器访问 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,但是在 Linq 检索之后通过在目标数据类中实现它来执行“ToShortTimeString”和“ToShortDateString”转换。

于 2009-01-16T00:00:30.987 回答