如何在Entity Framework查询中将DateTime转换为TimeSpan

11

我有一个使用Entity Framework 6的LINQ查询:

var timeCapturesQuery = Context.TimeCaptures
    .Where(t =>
        && t.StartDateTime.TimeOfDay < endTime
        && t.EndDateTime.TimeOfDay > startTime);

EndTime和StartTime是TimeSpan类型的参数,StartDateTime和EndDateTime是datetime表中的列。

不幸的是,在运行时我收到了以下错误:

指定的类型成员“TimeOfDay”在LINQ to Entities中不受支持。仅支持初始化程序、实体成员和实体导航属性。

如何在此LINQ查询中从DateTime获取TimeSpan(即来自SQL中datetimetime)?


抱歉,我不认为这会有帮助。您将DateTime转换为字符串,然后再转换回DateTime,然后调用属性,这会导致错误。还要记住,StartDateTime是表上的列,而不是参数。 - James Newton-King
保罗所说的可能有效。 - Berkay Yaylacı
1
这个解决方案怎么样? - CodeMaster
3个回答

9

看起来你要找的是 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);

我猜这种方法的缺点是它会截断掉毫秒级别的TimeSpan值。 - John Zabroski

2
“TimeOfDay”属性在LINQ to Entities中不受支持,因此您可以尝试使用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);

另一个更简单的选项是比较日期时间。我们已经将时间跨度转换为日期时间,并且可以使用LINQ to Entities创建一个简单的条件,应该能够工作,因为我们没有使用任何日期时间属性。
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);

1
DATEPART 没有“timeofday”参数。 - James Newton-King

1

1
放弃EF不是一个选项。 - James Newton-King

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接