简体   繁体   English

如何在实体框架查询中将DateTime转换为TimeSpan

[英]How to convert DateTime to TimeSpan in Entity Framework query

I have this LINQ query with Entity Framework 6: 我有Entity Framework 6的LINQ查询:

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

EndTime and StartTime are parmeters of type TimeSpan , StartDateTime and EndDateTime are columns on the table of datetime . EndTime和StartTime是TimeSpan类型的参数,StartDateTime和EndDateTime是datetime表上的列。

Unfortunately I get this error when it is run: 不幸的是,我在运行时收到此错误:

The specified type member 'TimeOfDay' is not supported in LINQ to Entities. LINQ to Entities不支持指定的类型成员'TimeOfDay'。 Only initializers, entity members, and entity navigation properties are supported. 仅支持初始值设定项,实体成员和实体导航属性。

How can I get a TimeSpan from a DateTime (ie the time from datetime in SQL) in this LINQ query? 如何在此LINQ查询中从DateTime(即SQL中的datetimetime )获取TimeSpan

Looks like DbFunctions.CreateTime is what you're looking for: 看起来像DbFunctions.CreateTime正在寻找:

When used as part of a LINQ to Entities query, this method invokes the canonical CreateTime EDM function to create a new TimeSpan object. 当用作LINQ to Entities查询的一部分时,此方法调用规范的CreateTime EDM函数来创建新的TimeSpan对象。

So to get results between two times, you can: 因此,要在两次之间获得结果,您可以:

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);

The property TimeOfDay does not supported in LINQ to Entities so you can try using SqlFunctions.DatePart method instead. LINQ to Entities中不支持属性TimeOfDay,因此您可以尝试使用SqlFunctions.DatePart方法。

You should probably also convert your TimeSpans into DateTimes . 您可能还应该将TimeSpans转换为DateTimes。

I think this should work (assuming the TimeSpans is from the begining of the day): 我认为这应该有效(假设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));

Edit 编辑

As mentioned in the comments the specific property TimeOfTheDay is not supported in DatePart method. 如评论中所述,DatePart方法不支持特定属性TimeOfTheDay。

Maybe EntityFunctions.DiffNanoseconds method will work: 也许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 EDIT2

Another option which is much simpler and I think will work is just to compare the DateTimes. 另一个更简单的选项,我觉得可以用来比较DateTimes。

We've already converted the TimeSpans into DateTimes and we can create a simple condition using LINQ to Entities and it should work because we are not using any of the DateTimes properties. 我们已经将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);

It looks like Linq2db supports it. 看起来Linq2db支持它。

https://github.com/linq2db/linq2db/blob/1ff760181717c73859ab3a5519f76943241d460f/Source/Linq/Expressions.cs https://github.com/linq2db/linq2db/blob/1ff760181717c73859ab3a5519f76943241d460f/Source/Linq/Expressions.cs

Of course it is not very good option to use new ORM. 当然,使用新的ORM并不是一个很好的选择。
But I think it is most weak part of EF after performance. 但我认为这是EF表现最弱的部分。
So maybe it is good time to think again. 所以也许是再次思考的好时机。

With Linq2db you can provide custom SQL logic (you need to create own expression). 使用Linq2db,您可以提供自定义SQL逻辑(您需要创建自己的表达式)。 It was never necessary for me, but you can read this for more details. 这对我来说从来没有必要,但你可以阅读这个以获取更多细节。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM