我的应用程序有一个内置的日历系统,它们的数据库模式如下所示:
CalendarItem( CalendarItemId bigint, Start datetime, Length int, Blargh nvarchar(MAX) )
Start
是事件开始时的UTC日期时间值,Length
是事件的长度(以秒为单位)。全天活动从0000h开始,长度为86400。
我正在使用Linq和Entity Framework,我想查找属于日期范围的事件。很容易找到在两个日期时间之间开始的事件,但我不知道如何在两个日期时间之间找到结束的事件。
这是我目前的代码:
public IEnumerable<CalendarItem> GetCalendarItems(DateTime from, DateTime to) {
var events = from c in db.CalendarItems
where c.Start >= from && c.Start <= to
orderby c.Start
select c;
return events;
}
如果我使用的是T-SQL,我需要使用DATEADD
将Length
秒添加到Start
以提供End
日期时间,然后这会有效,但我认为我不能在Linq做到这一点。我该怎么办?
答案 0 :(得分:2)
使用ToList()函数进行编辑:
如果我正确地读了这个,你会想要:
var events = (from c in db.CalendarItems
where c.Start >= from && c.Start <= to
orderby c.Start
select c).ToList();
events = events.Where(e => e.Start.AddSeconds(Length) <= to);
return events;
然后,这将为您提供在指定日期范围内开始和结束的事件。
有关DateTime.AddSeconds()的更多信息,请访问this link。
答案 1 :(得分:1)
在使用ToList()
功能之前,您需要先调用DateTime.AddSeconds
。否则编译器会抱怨它无法找到AddSeconds
函数,因为您的LINQ查询将被转换为SQL而SQL不包含此DateTime.AddSeconds
函数。
var events = (from c in db.CalendarItems
where c.Start >= from && c.Start <= to
orderby c.Start
select c).ToList();
events = events.Where(e => e.Start.AddSeconds(Length) <= to);
return events;
编辑:纠正了我的逻辑,答案现在与IronMan84相同。
答案 2 :(得分:0)
我评估了.ToList
方法,但它们效率低下,因为在修改它以返回发生的事件(无论它们是否在其中开始或结束)时,它会从数据库中获取许多不相关的结果
我还查看了SqlFunctions方法,但它们不存在于EF1.0中。
我最终在我的实体上下文中使用了一个带有强类型导入的Sproc。它并不完美,但它比替代品更好。
当项目最终升级到.NET4时,我将切换到SqlFunctions。无论如何,感谢您的所有建议!