Translate List<T>.Exists to Queryable.Any#38226
Open
m-x-shokhzod wants to merge 3 commits intodotnet:mainfrom
Open
Translate List<T>.Exists to Queryable.Any#38226m-x-shokhzod wants to merge 3 commits intodotnet:mainfrom
m-x-shokhzod wants to merge 3 commits intodotnet:mainfrom
Conversation
Rewrites List<T>.Exists(predicate) to AsQueryable().Any(predicate) in QueryableMethodNormalizingExpressionVisitor, mirroring the existing ICollection<T>.Contains conversion. The Predicate<T> lambda is rebuilt as Func<T, bool> so the resulting Queryable.Any call type-checks. Flips four placeholder tests (Where_Join_Exists, _Inequality, _Constant, Where_Join_Not_Exists) from AssertTranslationFailed to AssertQuery, and populates the SqlServer SQL baselines with the EXISTS subquery output. Fixes dotnet#17762
- Wrap Cosmos overrides for the 4 Where_Join_*Exists* tests in AssertTranslationFailed, matching the existing Cosmos pattern for navigation-collection Any-style queries (Issue dotnet#17246). The base test used to be wrapped in AssertTranslationFailed which covered Cosmos; after flipping the base to AssertQuery for the providers that can now translate, the failure-assertion has to live on Cosmos's override. - Correct the expected SqlServer SQL for Where_Join_Exists_Constant and Where_Join_Not_Exists. EF's optimizer simplifies Any(o => false) and !Any(o => false) at translation time, so the EXISTS subquery does not appear in the emitted SQL. Pattern matches the existing Not_Any_false baseline in NorthwindAggregateOperatorsQuerySqlServerTest.
EF's optimizer recognizes that c.CustomerID == \"ALFKI\" && Exists(o => false) short-circuits to false and eliminates the entire predicate, including the customer-id filter. Actual emitted SQL is just \`WHERE 0 = 1\`, not \`WHERE [c].[CustomerID] = N'ALFKI' AND 0 = 1\`.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Rewrites
List<T>.Exists(predicate)toAsQueryable().Any(predicate)inQueryableMethodNormalizingExpressionVisitor, mirroring the existingICollection<T>.Containsconversion. ThePredicate<T>lambda is rebuilt asFunc<T, bool>so the resultingQueryable.Anycall type-checks.TryConvertListExistsToQueryableAnyhelper alongsideTryConvertCollectionContainsToQueryableContainsList<T>(other types likeArray.Existsare out of scope)new List<T>/new {...}) or the predicate is a non-lambda delegateWhere_Join_Exists,_Inequality,_Constant,Where_Join_Not_Exists) tagged with// Issue #17762fromAssertTranslationFailedtoAssertQueryfalsepredicates)AssertTranslationFailedper Cosmos's existingIssue #17246pattern for navigation-collectionAnytranslationsFixes #17762