efcore: DateTimeOffset expression could not be translated in EF.Sqlite 2.2.0
Simple LINQ query could not be translated in EF.Sqlite 2.2:
queryable.Where(e => e.CreationDate > DateTimeOffset.Now)
It worked with EF.Sqlite 2.1 and EF.SqlServer 2.2.
Exception message:
System.InvalidOperationException: Error generated for warning 'Microsoft.EntityFrameworkCore.Query.QueryClientEvaluationWarning: The LINQ expression 'where ([e].CreationDate > DateTimeOffset.Now)' could not be translated and will be evaluated locally.'.
Stack trace:
at Microsoft.EntityFrameworkCore.Diagnostics.EventDefinition`1.Log[TLoggerCategory](IDiagnosticsLogger`1 logger, WarningBehavior warningBehavior, TParam arg, Exception exception)
at Microsoft.EntityFrameworkCore.Internal.RelationalLoggerExtensions.QueryClientEvaluationWarning(IDiagnosticsLogger`1 diagnostics, QueryModel queryModel, Object queryModelElement)
at Microsoft.EntityFrameworkCore.Query.RelationalQueryModelVisitor.WarnClientEval(QueryModel queryModel, Object queryModelElement)
at Microsoft.EntityFrameworkCore.Query.RelationalQueryModelVisitor.VisitWhereClause(WhereClause whereClause, QueryModel queryModel, Int32 index)
at Remotion.Linq.Clauses.WhereClause.Accept(IQueryModelVisitor visitor, QueryModel queryModel, Int32 index)
at Remotion.Linq.QueryModelVisitorBase.VisitBodyClauses(ObservableCollection`1 bodyClauses, QueryModel queryModel)
at Remotion.Linq.QueryModelVisitorBase.VisitQueryModel(QueryModel queryModel)
at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.VisitQueryModel(QueryModel queryModel)
at Microsoft.EntityFrameworkCore.Query.RelationalQueryModelVisitor.VisitQueryModel(QueryModel queryModel)
at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.CreateAsyncQueryExecutor[TResult](QueryModel queryModel)
at Microsoft.EntityFrameworkCore.Storage.Database.CompileAsyncQuery[TResult](QueryModel queryModel)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileAsyncQueryCore[TResult](Expression query, IQueryModelGenerator queryModelGenerator, IDatabase database)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass22_0`1.<CompileAsyncQuery>b__0()
at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore[TFunc](Object cacheKey, Func`1 compiler)
at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddAsyncQuery[TResult](Object cacheKey, Func`1 compiler)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileAsyncQuery[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](Expression expression)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.System.Collections.Generic.IAsyncEnumerable<TResult>.GetEnumerator()
at System.Linq.AsyncEnumerable.Aggregate_[TSource,TAccumulate,TResult](IAsyncEnumerable`1 source, TAccumulate seed, Func`3 accumulator, Func`2 resultSelector, CancellationToken cancellationToken) in D:\a\1\s\Ix.NET\Source\System.Interactive.Async\Aggregate.cs:line 118
Further technical details
EF Core version: 2.2.0 Database Provider: Microsoft.EntityFrameworkCore.Sqlite Operating system: Windows 10 1803 IDE: Visual Studio 2017 15.9.3
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 6
- Comments: 17 (11 by maintainers)
Neither one should work. đ But the second one is more likely to evaluate on the client in older versions of EF Core.
@smitpatel any chance of revisiting this now that youâve closed #13192?
If you just treat the SQLite database as a UTC
DateTimeOffset
(e.g. any incomingDateTimeOffset
gets converted to the UTCDateTime
, any outgoing gets converted back toDateTimeOffset
with offset +0) then courtesy of #13192 you should also be able to handle comparisons, assignments, etc. to localDateTimeOffset
values by converting them to their UTCDateTime
values first before binding to the query?So what can we do now? We are stuck on the old version because in our whole application is DateTimeOffset. Is there any workaround or solution? Will there be a fix?
instead of
queryable.Where(e => e.CreationDate > DateTimeOffset.Now)
try this
queryable.Where(e => e.CreationDate.CompareTo(DateTimeOffset.Now) > 0)
worked for me
There are few issues here in using value conversion.
DateTimeOffset.Now
being server evaluated always, SQLite does not have translation for that. So even though we try to use value converter after above issue is fixed, now we need to find translation ofDateTimeOffset.Now.UtcDateTime
. Which we may be able to condense toDateTime.Now
(though not necessary we can do that for any value converter. This is covered by #10434I hoped that with the conversion, a query like this would work translate:
Reopening so that we can follow on on why type conversions donât help. The original issue is still by-design.