Skip to content

Conversation

@roji
Copy link
Member

@roji roji commented Dec 29, 2025

Fixes #37424

Copilot AI review requested due to automatic review settings December 29, 2025 09:37
@roji roji requested a review from a team as a code owner December 29, 2025 09:37
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR enables SQL Server JSON mapping to non-max nvarchar columns by updating the type mapping logic to match on the base type name rather than the full type name with size specification. This allows users to map JSON data to columns like nvarchar(2000) instead of only nvarchar(max).

Key Changes

  • Modified the type mapping source to use StoreTypeNameBase instead of storeTypeName when determining JSON type mappings
  • Changed the pattern match from exact "nvarchar(max)" to base type "nvarchar", which matches any nvarchar variant
  • Added test coverage for both structural JSON types and primitive collections with non-max nvarchar sizes

Reviewed changes

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

File Description
src/EFCore.SqlServer/Storage/Internal/SqlServerTypeMappingSource.cs Updated JSON type mapping logic to match on base type name ("nvarchar") instead of full type name ("nvarchar(max)"), enabling flexible column sizing
test/EFCore.SqlServer.Tests/Storage/SqlServerTypeMappingSourceTest.cs Added test Json_can_be_mapped_to_nvarchar_non_max() to verify JSON can be mapped to nvarchar with explicit size constraints

The implementation is correct and follows the established pattern in the codebase. The WithTypeMappingInfo method properly applies the actual size from the mapping info to the returned type mapping, ensuring that nvarchar(2000) is preserved as the store type rather than being replaced with nvarchar(max).

@roji roji enabled auto-merge (squash) December 29, 2025 14:08
{
"json" => SqlServerStructuralJsonTypeMapping.JsonTypeDefault,
"nvarchar(max)" => SqlServerStructuralJsonTypeMapping.NvarcharMaxDefault,
"nvarchar" => SqlServerStructuralJsonTypeMapping.NvarcharMaxDefault,
Copy link
Member

Choose a reason for hiding this comment

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

If it's not nvarchar(max) you'd need to create a new mapping with the specified length as it's done for strings below

Copy link
Member Author

Choose a reason for hiding this comment

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

Good catch, thanks.

Copy link
Member Author

Choose a reason for hiding this comment

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

@AndriySvyryd on a deeper look...

First, the current behavior seems to be the same thing we had in 9.0, i.e. return an nvarchar(max) mapping that then gets cloned with the correct length facet (so the returned store type is indeed nvarchar(2000), not max).

Second, IIUC, if the user explicitly specifies a store type, for strings as well we don't go through the creation of a new string type mapping via the code you're referring to; we find nvarchar(max) or nvarchar (the base store type) in _storeTypeMappings, and then just return that (that gets cloned with the right size outside of SqlServerTypeMappingSource).

The "complicated" fragment which constructs new SqlStringStringTypeMappings kicks in only when there's no store type configured, and allows users to optionally specify the size via data annotations/fluent API. But I don't think we allow MaxLength to be configured on complex properties (they're not regular properties). In other words, if users want a non-max nvarchar, they have to currently specify the store type fully and directly, rather than rely on size data annotation/fluent API.

So I think the current thing is in line with what we're already doing for strings, but this is a tricky area, so definitely take a look and let me know what you think.

Copy link
Member

Choose a reason for hiding this comment

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

The "complicated" fragment which constructs new SqlStringStringTypeMappings kicks in only when there's no store type configured, and allows users to optionally specify the size via data annotations/fluent API. But I don't think we allow MaxLength to be configured on complex properties (they're not regular properties).

Sure, but we'll have to do it when #28591 is implemented. My preference is to have future-proof logic, but if you are going to port this this 10, then the simpler fix is better

Copy link
Member Author

@roji roji Jan 3, 2026

Choose a reason for hiding this comment

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

Let's go with the simple fix for now - I'm thinking we should maybe patch this, as it's affecting multiple users, and there isn't a really good workaround (aside from manually editing all migrations to remove the size). What's your opinion?

BTW #28591 seems to be far less relevant, now that SQL Server has a dedicated json type (and so do most/all other databases which support JSON). We should generally start viewing nvarchar JSON mapping as legacy, in the same way that SQL Server does. And although in theory json columns can have facets, in practice they don't... So I wouldn't worry too much about this.

Copilot AI review requested due to automatic review settings December 31, 2025 12:56
@roji roji requested a review from AndriySvyryd December 31, 2025 12:57
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

@AndriySvyryd AndriySvyryd disabled auto-merge January 2, 2026 20:53
@roji roji merged commit 46fd7b1 into dotnet:main Jan 3, 2026
12 of 13 checks passed
@roji roji deleted the SqlServerJson branch January 3, 2026 14:41
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.

EF10 SQL Server: JSON types mapped to nvarchar(x) (non-MAX) no longer work

2 participants