Skip to content

Support sql server 2025 json column#483

Open
projecteon wants to merge 1 commit into
fsprojects:masterfrom
projecteon:master-sqlserver2025-support
Open

Support sql server 2025 json column#483
projecteon wants to merge 1 commit into
fsprojects:masterfrom
projecteon:master-sqlserver2025-support

Conversation

@projecteon

Copy link
Copy Markdown

Where it breaks

src/SqlClient.DesignTime/SqlClientExtensions.fs:125 holds providerTypes — a dict keyed by sys.types.name. LoadDataTypesMap() reads every row of sys.types and calls getProvidedType, which does providerTypes.TryGetValue(name) and falls through to failwith ("Unexpected type: " + name) at line 590 when the name is unknown.

SQL Server 2025 adds json (system_type_id 244) to sys.types. Dict has no "json" key. Type provider dies loading the map — before it ever touches your query. That's why the error fires on any command against a 2025 database, even one that selects zero json columns.

Two fixes

Fix A — map json to nvarchar. Works today, no dependency bump.

Project pins Microsoft.Data.SqlClient 5.1.3 (src/SqlClient/SqlClient.fsproj:36, src/SqlClient.DesignTime/SqlClient.DesignTime.fsproj:31). JSON TDS support landed in MDS 6.0. Against a 5.1.3 client the server downgrades json columns to nvarchar(max) on the wire, so mapping it as NVarChar is honest, not a hack — same treatment sysname already gets at line 159.

Add to providerTypes, near the unicode string block:

    // SQL Server 2025 native json type. Mapped to NVarChar because
    // Microsoft.Data.SqlClient < 6.0 receives it as nvarchar(max) over TDS.
    "json", (SqlDbType.NVarChar, "System.String", false)

Result: json columns surface as string, json parameters send as nvarchar and the server implicitly converts on insert. findTypeInfoByProviderType uses Array.find on SqlDbType, so the extra NVarChar entry is shadowed by nvarchar — same as sysname, no new ambiguity.

Fix B — real JSON support. Needs MDS ≥ 6.0.

Bump both .fsproj PackageReferences to 6.x, then map to the extension value:

    "json", (enum<SqlDbType> 35, "System.String", false)   // Microsoft.Data.SqlDbTypeExtensions.Json

SqlDbTypeExtensions.Json = 35; System.Data.SqlDbType.Json only exists on .NET 9+, and this lib multi-targets netstandard2.0;net8.0;net471, so the raw enum cast is what's portable.

Fix B has a second edit you cannot skip. SqlClientExtensions.fs:496 does Enum.Parse(typeof, string row.["ProviderType"]) then findTypeInfoByProviderType. With MDS 6.0 the schema table reports ProviderType = 35 for json columns; Enum.Parse accepts the numeric string and yields enum 35, then Array.find throws KeyNotFoundException unless the dict entry above exists. Adding the entry satisfies both call sites.

Recommendation

Take Fix A. It's one line, unblocks your build immediately, and string is what you'd get from the 5.1.3 driver anyway. Fix B only buys you SqlJson / streaming / bulk-copy of json, and it drags a major driver upgrade across a type provider that gets loaded into the compiler process — worth doing deliberately, not as a build unblock.

Want me to apply Fix A and add a json column to tests/SqlClient.Tests/extensions.sql to cover it?

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.

1 participant