如何在entity framework查询中将DateTime转换为TimeSpan
我有Entity Framework 6的LINQ查询:
var timeCapturesQuery = Context.TimeCaptures .Where(t => && t.StartDateTime.TimeOfDay startTime);
EndTime和StartTime是TimeSpan
类型的参数,StartDateTime和EndDateTime是datetime
表上的列。
不幸的是,我在运行时收到此错误:
LINQ to Entities不支持指定的类型成员’TimeOfDay’。 仅支持初始化程序,实体成员和实体导航属性。
如何在此LINQ查询中从DateTime(即SQL中的datetime
的time
)获取TimeSpan
?
看起来像DbFunctions.CreateTime
正在寻找:
当用作LINQ to Entities查询的一部分时,此方法调用规范的CreateTime EDM函数来创建新的TimeSpan对象。
因此,要在两次之间获得结果,您可以:
var timeCapturesQuery = Context.TimeCaptures.Where(t => DbFunctions.CreateTime(t.StartDateTime.Hour, t.StartDateTime.Minute, t.StartDateTime.Second) < endTime && DbFunctions.CreateTime(t.EndDateTime.Hour, t.EndDateTime.Minute, t.EndDateTime.Second) > startTime);
LINQ to Entities不支持属性TimeOfDay,因此您可以尝试使用SqlFunctions.DatePart方法。
您可能还应该将TimeSpans转换为DateTimes。
我认为这应该有效(假设TimeSpans是从当天开始):
var now = DateTime.Now; var today = new DateTime(now.Year, now.Month, now.Day); var endDateTime = today + endTime; var startDateTime = today + startTime var timeCapturesQuery = Context.TimeCaptures.Where(t => SqlFunctions.DatePart("timeofday", t.StartDateTime) < SqlFunctions.DatePart("timeofday", endDateTime) && SqlFunctions.DatePart("timeofday", t.EndDateTime) > SqlFunctions.DatePart("timeofday", startDateTime));
编辑
如评论中所述,DatePart方法不支持特定属性TimeOfTheDay。
也许EntityFunctions.DiffNanoseconds方法可以工作:
var now = DateTime.Now; var today = new DateTime(now.Year, now.Month, now.Day); var endDateTime = today + endTime; var startDateTime = today + startTime var timeCapturesQuery = Context.TimeCaptures.Where(t => EntityFunctions.DiffNanoseconds(t.StartDateTime, endDateTime).Value < 0 && EntityFunctions.DiffNanoseconds(t.EndDateTime, startDateTime).Value > 0);
EDIT2
另一个更简单的选项,我觉得可以用来比较DateTimes。
我们已经将TimeSpans转换为DateTimes,我们可以使用LINQ to Entities创建一个简单的条件,它应该可以工作,因为我们没有使用任何DateTimes属性。
var now = DateTime.Now; var today = new DateTime(now.Year, now.Month, now.Day); var endDateTime = today + endTime; var startDateTime = today + startTime var timeCapturesQuery = Context.TimeCaptures.Where(t => t.StartDateTime < endDateTime && t.EndDateTime > startDateTime);
看起来Linq2db支持它。
当然,使用新的ORM并不是一个很好的选择。
但我认为这是EF表现最弱的部分。
所以也许是再次思考的好时机。
使用Linq2db,您可以提供自定义SQL逻辑(您需要创建自己的表达式)。 这对我来说从来没有必要,但你可以阅读这个以获取更多细节。