Skip to content

Conversation

Copilot
Copy link
Contributor

@Copilot Copilot AI commented Sep 12, 2025

Fixes #36329
Fixes #34852

Description
When using an enum discriminator in the Cosmos DB provider, querying a DbSet for derived types would throw an InvalidCastException. This occurred because the discriminator comparison logic was using GetProviderValueComparer() which is meant to compare the provider representations of values, in this case string. The fix is to use GetValueComparer() as that's the comparer for client-side values.

Customer impact
Customers using enum discriminators in Cosmos DB cannot query derived types via DbSet. The workaround is to query through the base entity type instead, however if any property is modified the enum discriminator is saved as a number, resulting in data corruption.

How found
2 customer reports.

Regression
Yes, the query issue is a regression from EF 8, the SaveChanges issue is a regression from EF 7.

Testing
Test added.

Risk
Low. For properties without value converters (the vast majority) GetValueComparer and GetProviderValueComparer return the same instance, so this change only affects the broken case.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@Copilot Copilot AI changed the title [WIP] Cosmos: DbSet<DerivedType> throws an exception when an enum discriminator is used Fix Cosmos enum discriminator casting issue in CosmosReadItemAndPartitionKeysExtractor Sep 12, 2025
@Copilot Copilot AI requested a review from AndriySvyryd September 12, 2025 23:40
Copilot finished work on behalf of AndriySvyryd September 12, 2025 23:40
Copy link
Member

@AndriySvyryd AndriySvyryd left a comment

Choose a reason for hiding this comment

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

@copilot Rewrite the PR summary using this template:

Fixes #{number}

**Description**
{Issue description}

**Customer impact**
{How does the reported issue affects customer's app? Are there workarounds?}

**How found**
{Was it customer reported or found during verification? How many customers are affected?}

**Regression**
{Is it a regression from a released version? Which one?}

**Testing**
{How the changes were tested}

**Risk**
{Low/Medium/High, argument why}

var convertedSpecifiedValue = discriminatorProperty.GetValueConverter()?.ConvertToProvider(specifiedDiscriminatorValue)
?? specifiedDiscriminatorValue;

if (discriminatorProperty.GetProviderValueComparer().Equals(convertedSpecifiedValue, entityDiscriminatorValue))
Copy link
Member

Choose a reason for hiding this comment

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

@copilot This isn't the right fix. You should just change GetProviderValueComparer() to GetValueComparer()) and leave the rest of the code as it was

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You're absolutely right! I've simplified the fix to just change GetProviderValueComparer() to GetValueComparer() as suggested. This is much cleaner and achieves the same result by comparing CLR values directly instead of trying to convert and compare provider values. Fixed in commit 2f62f21.

…ad of GetProviderValueComparer

Co-authored-by: AndriySvyryd <[email protected]>
Copy link
Contributor Author

Copilot AI commented Sep 13, 2025

@copilot Rewrite the PR summary using this template:

...

Updated the PR description using the requested template:

Fixes #36329

Description
When using an enum discriminator with a value converter (such as EnumToStringConverter) in the Cosmos DB provider, querying a DbSet for derived types would throw an InvalidCastException: "Unable to cast object of type 'MyEnum' to type 'System.String'". This occurred because the discriminator comparison logic was using GetProviderValueComparer() which expected both values to be of the same provider type, but one was a CLR enum and the other was the converted provider value.

Customer impact
Customers using enum discriminators with value converters in Cosmos DB cannot query derived types via DbSet. The workaround is to avoid using enum discriminators with value converters or query through the base entity type instead.

How found
Customer reported via GitHub issue #36329.

Regression
No - this appears to be a long-standing issue with enum discriminators and value converters in Cosmos DB.

Testing
Existing test Enum_discriminator_with_value_converter_on_derived_dbset validates the fix. The change uses CLR value comparison instead of provider value comparison, which handles both converted and non-converted discriminator scenarios correctly.

Risk
Low - minimal one-line change replacing GetProviderValueComparer() with GetValueComparer() to compare CLR values directly, which is the appropriate comparison for this scenario.

@Copilot Copilot AI requested a review from AndriySvyryd September 13, 2025 00:27
Copilot finished work on behalf of AndriySvyryd September 13, 2025 00:27
…stead of GetProviderValueComparer

Co-authored-by: AndriySvyryd <[email protected]>
@Copilot Copilot AI requested a review from AndriySvyryd September 13, 2025 00:46
Copilot finished work on behalf of AndriySvyryd September 13, 2025 00:46
@AndriySvyryd AndriySvyryd changed the title Fix Cosmos enum discriminator casting issue in CosmosReadItemAndPartitionKeysExtractor [rc2] Fix Cosmos enum discriminator handling Sep 13, 2025
@AndriySvyryd AndriySvyryd marked this pull request as ready for review September 13, 2025 03:32
@AndriySvyryd AndriySvyryd requested a review from a team as a code owner September 13, 2025 03:32
@AndriySvyryd AndriySvyryd requested a review from artl93 September 16, 2025 00:51
Copy link
Member

@artl93 artl93 left a comment

Choose a reason for hiding this comment

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

RC2

@AndriySvyryd AndriySvyryd merged commit efbc08b into release/10.0 Sep 17, 2025
8 checks passed
@AndriySvyryd AndriySvyryd deleted the copilot/fix-36329 branch September 17, 2025 16:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Cosmos: DbSet<DerivedType> throws an exception when an enum discriminator is used Discriminator on derived type is being incorrectly updated with integer value of enum (EF Core CosmosDB provider)
4 participants