-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Always convert to parameter query roots in relational #30966
Conversation
59a5170
to
7b17a5f
Compare
7b17a5f
to
b54e60a
Compare
@maumar FYI rebased on latest main |
@maumar I think this may intersect with some work @ajcvickers has planned (on metadata/type mapping of primitive collections), so it may be good to get this merged quickly before conflicts arise. |
@@ -126,6 +126,9 @@ | |||
<data name="CannotProduceUnterminatedSQLWithComments" xml:space="preserve"> | |||
<value>Can't produce unterminated SQL with comments when generating migrations SQL for {operation}.</value> | |||
</data> | |||
<data name="CompatibilityLevelTooLowForScalarCollections" xml:space="preserve"> | |||
<value>EF Core's SQL Server compatibility level is set to {compatibilityLevel}; compatibility level 130 (SQL Server 2016) is the minimum for most forms of querying of JSON arrays.</value> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: did we decide to mention compatibility level explicitly in exception messages? Either way, we should maybe unify with JsonValuePathExpressionsNotSupported
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I think it's useful to mention the required and current compatibility level in the exceptions we throw... This way users know right away what's going on.
Changed JsonValuePathExpressionsNotSupported to also include the compatibility level, check out the added commit.
b54e60a
to
62bf50a
Compare
The current implementation of primitive collections requires that providers opt into parameter query roots in preprocessing (inline query roots are opted into at the relational level). This was done in order to support legacy modes where e.g. OPENJSON isn't supported, and so we get just a normal parameter with Enumerable Contains instead of ParameterQueryRootExpression with Queryable Contains, and the legacy translation kicks in (IN with constants).
With this PR, we now always get a ParameterQueryRootExpression. If the provider doesn't override RelationalQueryableMethodTranslatingExpressionVisitor.TranslateCollection (e.g. to implement OPENJSON), there's now a fallback path in VisitMethodCall that identifies Contains and generates the legacy InExpression. Note that this requires changing error handling in QueryableMethodTranslatingEV: we can no longer throw immediately if the source can't be translated, to allow this fallback translation to work.
This also allows us to always set ElementTypeMapping on the type mapping returned by the type mapping source; we previously didn't set it for old SQL Server, since that controlled whether nav expansion interpreted a property as queryable or not.
After this PR, the only place which cares about whether the database supports OPENJSON is RelationalQueryableMethodTranslatingExpressionVisitor.TranslateCollection, and providers no longer need to mess around in preprocessing.
Note that at the non-relational level, inline and parameter query roots still aren't generated by default, since that would require fixing up Cosmos and InMemory. We can do that later.
Note: this PR is based on top of #30956, review the 2nd commit only.