我正在使用ObjectDataSource访问业务类,并尝试生成对用户有意义的输出。返回值描述了一个类(如在教室和教学中,而不是软件)。我希望将课程时间显示为这样的范围:“上午9:00 - 上午10:00”。
这是我用来提取数据的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的新手,我假设在投影之后发生了对ToShortTimeString的C#调用。任何人都可以帮我弄清楚如何获得我正在寻找的字符串?
答案 0 :(得分:4)
原因是查询正在LINQ to SQL中使用。 LINQ to SQL将查询视为表达式树。它具有为某些方法定义的映射(例如,Contains
),但由于它并不真正执行它们,因此它无法对任意方法起作用。它解析查询并将其提交给SQL Server。查询的等效项将作为数据库服务器上的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();
答案 1 :(得分: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变量通过属性getter:
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”转换。