-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Description
Row value is part of the SQL standard -though not supported by every database in all places- and it allows using the following syntax (for example in a where clause):
WHERE (timestamp, id) > ('2019-03-10 00:00:00+00:00', 1032749689)This is in particular a highly valuable syntax when doing keyset/seek/cursor pagination, and being able to use it with databases that support it will be a big win for seek pagination in particular, but also composite conditions that can gain from this syntax in general.
The row value syntax above is equivalent, in theory, to something like this:
WHERE
(timestamp > '2019-03-10 00:00:00+00:00') OR
(timestamp = '2019-03-10 00:00:00+00:00' AND id > 1032749689)But, for one, this logic condition becomes more complex the more columns you have. In addition, the db implementation of row value will usually be much more efficient than this (there are a few things you can do that can help the db engine in the above condition, but it doesn't look nice or readable).
More info about row value here: https://use-the-index-luke.com/sql/partial-results/fetch-next-page#sb-row-values
My use case is a package I worked on that fully implements keyset pagination with EF Core, but does so by building the expressions so that it translates to the logical condition syntax above. I could use a row value translator.
For a related issue to keyset pagination see this: #9115
Proposed solution
What I would love to see is a db function that EF Core understands and translates into the row value syntax for db providers that support it. Something like this:
var timestamp = ...;
var id = 1032749689;
// One option:
.Where(b => EF.Functions.GreaterThan(new[] { b.Column1, b.Column2 }, new[] { 1, 2 }))
// Another option with a tuple override:
.Where(b => EF.Functions.GreaterThan((b.Column1, b.Column2), new[] { 1, 2 }))
// Translates to sql:
// WHERE (timestamp, id) > ('2019-03-10 00:00:00+00:00', 1032749689)One thing I'm not sure of is if there's a system in place that would allow a consumer to know if the current database provider supports this syntax or not. Because I want to be able to fallback to my implementation in such a case.
If this seems like an interesting and feasible addition, I'm willing to work on it.