-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Query: DateTime.Add* functions throw exception when argument is larger than int range #7756
Comments
Is that not in EF6? |
As I understand, DbFunctions type is not part of Entity Framework Core, EF Core works with DateTime methods directly: which is fine for the API, since DateTime.AddMilliseconds accepts But it's not clear if EF Core works around the 32-bit limitation in SQL Server. In SQL server, DATEADD function works with 32 bit
|
@george-polevoy, is there any reason not to use the other Add overloads (e.g. |
@roji, the reason for me is that code get's complicated with the workaround you suggest, even for very simple things. This example only works under for the entire interval of 24 days: var q = from i in ctx.GenerateLongSequence
let localStart = start.AddMilliseconds(i.I * step.TotalMilliseconds),
let localEnd = start.AddMilliseconds( (i.I + 1) * step.TotalMilliseconds)
// .. You can see that simple thing turns into a non-trivial date time manupulation to apply the workaround: var q = from i in ctx.GenerateLongSequence
where i.I <= n
let startOffsetMillis = stepMillis * i.I
let startOffsetDays = (int)(startOffsetMillis / 86400000L)
let localStart = DbFunctions.AddMilliseconds(DbFunctions.AddDays(start, startOffsetDays), (int)(startOffsetMillis % 86400000L))
let endOffsetMillis = stepMillis * (i.I + 1)
let endOffsetDays = (int)(endOffsetMillis / 86400000L)
let localEnd = DbFunctions.AddMilliseconds(DbFunctions.AddDays(start, endOffsetDays), (int)(endOffsetMillis % 86400000L))
// .. |
We generate Invalid SQL here when we get value which is larger than int range since we are not doing any validation on the arguments value. We need to decide if we want to tackle with the value or just do client eval. |
We will try switching to client eval conditionally if the number would overflow. If the query must be store translated, then it must be written in a way that can be translated. |
It's also possible to check whether the number would overflow, and break it down into larger units (e.g. days), in effect doing the non-trivial code sample from this comment. This would allow store evaluation even when the number of milliseconds would overflow 32-bit, but isn't trivial to do. |
In case it helps, My answer was:
DbFunctions.DiffDays(a, b) < 24 && DbFunctions.DiffDays(a, b) > -24 ?
(long)DbFunctions.DiffMilliseconds(a, b) :
(long)DbFunctions.DiffDays(a, b) * 86400000 +
(long)DbFunctions.DiffMilliseconds(DbFunctions.AddDays(a, DbFunctions.DiffDays(a, b)), b)
|
@divega - Should this be bug fix rather than enhancement? |
AddMilliseconds and other functions only allows for 2^31 milliseconds, which is only about 24 days.
In a query, which requires millisecond offsets larger than 24 days, you would need something like:
The text was updated successfully, but these errors were encountered: