Skip to content

Fix #3570: Support empty collection when using Contains (#3573) - #3602

Merged
xuzhg merged 1 commit into
mainfrom
xuzhg/port-3570-empty-contains-to-main
Aug 25, 2026
Merged

xuzhg merged 1 commit into
mainfrom
xuzhg/port-3570-empty-contains-to-main

Conversation

@xuzhg

@xuzhg xuzhg commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

LINQ queries such as 'skus.Contains(x.Sku)' translate to an OData 'in' filter. When the source collection is empty, the client threw InvalidOperationException (ALinq_ContainsNotValidOnEmptyCollection) instead of producing a valid query.

Emit the empty 'in' collection literal (e.g. 'Name in ()') for an empty collection. The OData query parser already supports this form and evaluates it to no matches, so the query now returns an empty result set instead of failing.

Updated the two client tests that asserted the old throwing behavior to verify the new 'in ()' translation.

  • Remove unused ALinq_ContainsNotValidOnEmptyCollection resource string

Address PR review comment: the resource string is no longer referenced after allowing empty collections in Contains. Remove it from SRResources.resx, SRResources.Designer.cs, and the SRResourcesTests InlineData.

Ports the #3570 fix from dev-9.x to main.

LINQ queries such as skus.Contains(x.Sku) translate to an OData in
filter. Previously, an empty source collection caused the client to throw
InvalidOperationException.

This change:

  • Emits an empty in collection, such as Name in ().
  • Updates string and enum regression tests.
  • Removes the now-unused ALinq_ContainsNotValidOnEmptyCollection resource.

The OData.NET URI parser already supports empty in collections and evaluates
them as matching no values.

Issues

This pull request fixes #xxx.

Description

Briefly describe the changes of this pull request.

Checklist (Uncheck if it is not completed)

  • Test cases added
  • Build and test with one-click build and test script passed

Additional work necessary

If documentation update is needed, please add "Docs Needed" label to the issue and provide details about the required document change in the issue.

Repository notes

Team members can start a CI build by adding a comment with the text /AzurePipelines run to a PR. A bot may respond indicating that there is no pipeline associated with the pull request. This can be ignored if the build is triggered.

Team members should not trigger a build this way for pull requests coming from forked repositories. They should instead trigger the build manually by setting the "branch" to refs/pull/{prId}/merge where {prId} is the ID of the PR.

* Fix #3570: Support empty collection when using Contains

LINQ queries such as 'skus.Contains(x.Sku)' translate to an OData 'in'
filter. When the source collection is empty, the client threw
InvalidOperationException (ALinq_ContainsNotValidOnEmptyCollection)
instead of producing a valid query.

Emit the empty 'in' collection literal (e.g. 'Name in ()') for an empty
collection. The OData query parser already supports this form and
evaluates it to no matches, so the query now returns an empty result set
instead of failing.

Updated the two client tests that asserted the old throwing behavior to
verify the new 'in ()' translation.

* Remove unused ALinq_ContainsNotValidOnEmptyCollection resource string

Address PR review comment: the resource string is no longer referenced
after allowing empty collections in Contains. Remove it from SRResources.resx,
SRResources.Designer.cs, and the SRResourcesTests InlineData.
@xuzhg
xuzhg requested review from WanjohiSammy and a lite review from Copilot and removed request for Copilot August 25, 2026 19:15
@xuzhg

xuzhg commented Aug 25, 2026

Copy link
Copy Markdown
Contributor Author

/AzurePipelines run

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the OData Client LINQ-to-URI translation so Enumerable.Contains(...) over an empty in-memory collection no longer throws, and instead emits an empty in collection literal (in ()) which the OData URI parser treats as “matches nothing”.

Changes:

  • Translate empty Contains source collections to in () instead of throwing InvalidOperationException.
  • Update client translation unit tests for string and enum cases to assert the new in () output.
  • Remove the now-unused ALinq_ContainsNotValidOnEmptyCollection resource and its test coverage entry.

Reviewed changes

Copilot reviewed 4 out of 5 changed files in this pull request and generated no comments.

Show a summary per file
File Description
test/UnitTests/Microsoft.OData.Client.Tests/Resources/SRResourcesTests.cs Removes the resource key from the resource-string validation test data.
test/UnitTests/Microsoft.OData.Client.Tests/DataServiceQueryProviderTests.cs Updates LINQ translation tests to expect Name in () / Color in () instead of exceptions.
src/Microsoft.OData.Client/SRResources.resx Deletes the unused ALinq_ContainsNotValidOnEmptyCollection string resource.
src/Microsoft.OData.Client/SRResources.Designer.cs Removes the generated accessor property for the deleted resource key.
src/Microsoft.OData.Client/ALinq/ExpressionWriter.cs Changes Contains list-literal serialization to allow empty collections and emit ().
Files not reviewed (1)
  • src/Microsoft.OData.Client/SRResources.Designer.cs: Generated file

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@xuzhg
xuzhg merged commit cccf9d1 into main Aug 25, 2026
3 checks passed
@xuzhg
xuzhg deleted the xuzhg/port-3570-empty-contains-to-main branch August 26, 2026 16:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support empty collection when using Contains

2 participants