Calling .Where(predicate) on a DbSet where the predicate uses .CompareTo between a DateTime Entity property and DateTime.UtcNow causes the entire Where expression to be dropped and not included in the generated query.
Include a complete code listing (or project/solution) that we can run to reproduce the issue.
Partial code listings, or multiple fragments of code, will slow down our response or cause us to push the issue back to you to provide code to reproduce the issue.
```c#
var result = await context.DbSetName
.Where(s => s.ExpiryDate.CompareTo(now) > 0)
.Skip(0)
.Take(10)
.ToListAsync(cancellationToken);
Instead, the following works - is there any reason CompareTo is not supported, or why an exception is not thrown? (would be quite disasterous to unintentionally miss out on the entire expression if it's built based on conditions)
```c#
var result = await context.DbSetName
.Where(s => s.ExpiryDate > 0)
.Skip(0)
.Take(10)
.ToListAsync(cancellationToken);
EF Core version: 2.1.0-rc1-final
Database Provider: Microsoft.EntityFrameworkCore.SqlServer
Operating system: Windows 10 x64
IDE: JetBrains Rider 2018.1
Translation of DateTime.CompareTo is not currently supported. The query will use client side evaluation if it is enabled. See https://docs.microsoft.com/en-us/ef/core/querying/client-eval
In your case you can switch to this to get server evaluation.
.Where(s => s.ExpiryDate > now)
Hi @pmiddleton
Yeah - as I mentioned it's working by changing it to that.
The link you supplied, which shows "ConfigureWarnings" is great though - that answers my question around throwing warnings when EF is evaluating client-side.
Thanks!
@ajcvickers @smitpatel I did some research into this. Currently, I can see we have a StringCompareTranslator which handles both Compare and CompareTo. If I expand that class out to also support DateTime, my tests seem to suggest it then generates the correct comparisons in the where clause.
This raises the question, if this is the right solution, what other types would we want to support while making this change? Taking a quick look at the .NET documentation, the CompareTo is supported on:
System.Guid.CompareTo(Object)聽Method
System.String.CompareTo(String)聽Method
System.Byte.CompareTo(Byte)聽Method
System.Int16.CompareTo(Int16)聽Method
System.Int32.CompareTo(Int32)聽Method
System.Int64.CompareTo(Int64)聽Method
System.Char.CompareTo(Object)聽Method
System.Single.CompareTo(Single)聽Method
System.Char.CompareTo(Char)聽Method
System.Guid.CompareTo(Guid)聽Method
System.Enum.CompareTo(Object)聽Method
System.Double.CompareTo(Double)聽Method
System.SByte.CompareTo(SByte)聽Method
System.UInt16.CompareTo(Object)聽Method
System.UInt64.CompareTo(UInt64)聽Method
System.UInt32.CompareTo(UInt32)聽Method
System.Boolean.CompareTo(Boolean)聽Method
Thoughts on direction here? Do you want to support Compare and CompareTo everywhere or just limit it to String and a select few other types? One translator class to rule them all?
One class to rule them all.
@smitpatel - so you're going to add it to RelationalQueryModelVisitor ;)
May be RelationalQueryableExpressionVisitor 馃槒
@smitpatel See how you like them apples...
Most helpful comment
Translation of DateTime.CompareTo is not currently supported. The query will use client side evaluation if it is enabled. See https://docs.microsoft.com/en-us/ef/core/querying/client-eval
In your case you can switch to this to get server evaluation.