dotnet / efcore

EF Core is a modern object-database mapper for .NET. It supports LINQ queries, change tracking, updates, and schema migrations.
https://docs.microsoft.com/ef/
MIT License
13.77k stars 3.18k forks source link

work with timespan and compare them #31196

Open julienGrd opened 1 year ago

julienGrd commented 1 year ago

Hello guys, i migrate an old .net framework with entity framework 6 app to .NET 7, and i have to deal with time comparison which i don't find equivalent in EF Core. I don't find also documentation about it

the use case is simple, i want for example all events who start before 15h30

in entity framework the code is like that (with dtDeb a DateTime)

var lListEvents = dbcontext.Events.Where(e => EntityFunctions.CreateTime(e.DtDeb.Hour,  e.DtDeb.Minute, 0)  <
EntityFunctions.CreateTime(15, 30, 0) );

if ef core, i try this but obviously its not work

var lListEvents = dbcontext.Events.Where(e => new Timespan(e.DtDeb.Hour,  e.DtDeb.Minute, 0)  <
new Timespan(15, 30, 0) );

what the best way to achieve this ?

thanks for your help !

ajcvickers commented 1 year ago

Note for triage: this is the SQL generated by EF6:

SELECT
    [Extent1].[Id] AS [Id],
    [Extent1].[DtDeb] AS [DtDeb]
    FROM [dbo].[Books] AS [Extent1]
    WHERE (convert (time,convert(varchar(255), DATEPART (hour, [Extent1].[DtDeb])) + ':' + convert(varchar(255), DATEPART (minute, [Extent1].[DtDeb])) + ':' + str(cast(0 as float(53)), 10, 7), 121)) < (convert (time,convert(varchar(255), 15) + ':' + convert(varchar(255), 30) + ':' + str(cast(0 as float(53)), 10
, 7), 121))
AndriySvyryd commented 1 year ago

The EF6 translation is likely horrible perf-wise. You could just compare the components yourself:

var lListEvents = dbcontext.Events.Where(e => e.DtDeb.Hour < 15 || (e.DtDeb.Hour == 15 &&  e.DtDeb.Minute < 30));