Skip to content

Upgrade to .NET 10 and Microsoft.Data.SqlClient 6.x#3656

Open
souvikghosh04 wants to merge 13 commits into
mainfrom
Usr/sogh/upgrade-net10-sqlclient6
Open

Upgrade to .NET 10 and Microsoft.Data.SqlClient 6.x#3656
souvikghosh04 wants to merge 13 commits into
mainfrom
Usr/sogh/upgrade-net10-sqlclient6

Conversation

@souvikghosh04

@souvikghosh04 souvikghosh04 commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Joint runtime + driver bump to unblock two new SQL datatypes — JSON (#2768) and Vector (#2767).

This is a no-behavior-change prerequisite PR. It does not implement JSON or Vector itself; it raises the runtime and driver floor so the companion feature PRs can compile and run.

WHY BOTH BUMPS ARE REQUIRED TOGETHER

Two separate datatype features both depend on this baseline:

  1. JSON ([Enh]: Support JSON data type for MSSQL #2768) — needs the .NET 10 BCL enum value.
    SqlDbType.Json (numeric value 35) is a BCL enum value in System.Data, added in .NET 9 and present in .NET 10. It is NOT a Microsoft.Data.SqlClient symbol — SqlClient does not get to add values to a BCL enum it does not own. On .NET 8, the SqlDbType enum stops at DateTimeOffset = 34, so

    Enum.TryParse<SqlDbType>("json", ignoreCase: true, out _)
    

    in TypeHelper.GetSystemTypeFromSqlDbType returns false regardless of which SqlClient version is installed. The companion feature PR for [Enh]: Support JSON data type for MSSQL #2768 plans to add a single dictionary entry

    [SqlDbType.Json] = typeof(string)
    

    which simply will not compile on net8.0.

  2. Vector ([Enh]: Support Vector data type in MSSQL #2767) — needs Microsoft.Data.SqlClient 6.1.x.
    The SqlVector type (extending System.Data.SqlTypes) was introduced in Microsoft.Data.SqlClient 6.1.0. DAB's current driver (5.2.3) has no such type, so vector columns/parameters cannot be discovered or round-tripped. The Vector foundation work (Foundation for adding support for Vector Data Type #3654, child of [Enh]: Support Vector data type in MSSQL #2767) requires the driver to be on the 6.1.x line. This PR pins 6.1.5.

Because JSON needs .NET 10 and Vector needs SqlClient 6.1.x, and both feature PRs build on the same baseline, both upgrades must land together as a single prerequisite.

WHY .NET 10 AND NOT .NET 9

  • .NET 10 is the current Long-Term Support release (Nov 2025+).
  • .NET 9 is Standard-Term Support, EOL May 2026.
  • DAB's current .NET 8 line reaches EOL November 2026.

Going straight to LTS avoids a second forced upgrade inside 12 months.

WHY SqlClient 6.1.x AND NOT 7.x

6.1.5 already delivers everything these features need: SqlVector (6.1) for Vector, and JSON support paired with the .NET 10 BCL SqlDbType.Json enum. 7.0 introduces a breaking change — the Azure auth stack (Azure.Core, Azure.Identity, Microsoft.Identity.Client) is extracted out of the core package into a separate Microsoft.Data.SqlClient.Extensions.Azure package — which would affect DAB's managed-identity / Entra ID auth paths and is out of scope for a no-behavior-change PR. Issue #3422's intent (get off the 2-versions-behind 5.2.3 line) is satisfied by 6.1.x. A move to 7.x is deferred to a dedicated follow-up.

SCOPE OF CHANGES (NO BEHAVIOR CHANGE INTENDED)

Runtime / SDK pin:

  • global.json: 8.0.420 -> 10.0.301

Target framework (all 11 src/**/*.csproj):

  • net8.0 -> net10.0

NuGet packages (Directory.Packages.props):

  • Microsoft.Data.SqlClient 5.2.3 -> 6.1.5
  • Microsoft.Extensions.Caching.Memory 8.0.1 -> 10.0.0
  • Microsoft.Extensions.Caching.Abstractions 9.0.0 -> 10.0.0
  • Microsoft.Extensions.Primitives 9.0.0 -> 10.0.0
  • Microsoft.Extensions.Configuration.Binder 9.0.0 -> 10.0.0
  • Microsoft.Extensions.Configuration.Json 9.0.0 -> 10.0.0
  • Microsoft.Extensions.Caching.StackExchangeRedis 9.0.3 -> 10.0.0

The Microsoft.Extensions.* bumps are required because OpenTelemetry's transitive chain (Microsoft.Extensions.Logging.Configuration 10.0.0) demands Configuration.Binder >= 10.0.0 — staying on 9.0.0 produces NU1605 package-downgrade errors (warning-as-error).

Service.csproj (Microsoft.NET.Sdk.Web) — drop now-redundant PackageReferences (NU1510, warning-as-error):

  • Microsoft.Extensions.Configuration.Binder (in shared framework)
  • Microsoft.Extensions.Configuration.Json (in shared framework)

Azure DevOps pipelines (9 occurrences across 8 files):

  • UseDotNet@2 version: 8.0.x -> 10.0.x

Container base images (Dockerfile):

  • mcr.microsoft.com/dotnet/sdk:8.0-cbl-mariner2.0 -> 10.0-azurelinux3.0
  • mcr.microsoft.com/dotnet/aspnet:8.0-cbl-mariner2.0 -> 10.0-azurelinux3.0
    (cbl-mariner2.0 tag does not exist for .NET 9+; Azure Linux 3.0 is
    Microsoft's documented successor.)

Aspire AppHost (src/Aspire.AppHost/AppHost.cs):

  • WithArgs("-f", "net8.0") -> WithArgs("-f", "net10.0") (mssql + pg)

Build/publish scripts:

  • scripts/publish.ps1: $dotnetTargetFrameworks net8.0 -> net10.0
  • scripts/create-manifest-file.ps1: $dotnetTargetFrameworks + hashtable
    keys net8.0_{rid} -> net10.0_{rid}
    (TODO marker: release-engineering to
    confirm download URLs/hashes resolve)

License file rename:

  • external_licenses/Microsoft.Data.SqlClient.SNI.5.2.0.License.txt -> external_licenses/Microsoft.Data.SqlClient.SNI.6.0.2.License.txt
    (SqlClient 6.1.5 depends on Microsoft.Data.SqlClient.SNI.runtime 6.0.2.)
  • scripts/notice-generation.ps1: path updated to match
  • TODO marker at top of license file: contents still 5.2.0 text; release-engineering to refresh from upstream before merge.

SUPPRESSED ASPDEPR008 (warning-as-error) — DELIBERATE

ASP.NET Core 10 deprecates IWebHostBuilder / IWebHost in favor of WebApplicationBuilder / IHost. Two locations in this repo still consume the obsolete types and would block compilation under the repo's TreatWarningsAsErrors=true setting:

  • src/Service/Program.cs (2 sites): test-only helpers CreateWebHostBuilder + CreateWebHostFromInMemoryUpdatableConfBuilder are consumed by the existing TestServer fixture which takes IWebHostBuilder.
  • src/Service.Tests/Configuration/ConfigurationTests.cs (3 sites): the consumer of those helpers.

Migrating from WebHost to HostBuilder/WebApplicationBuilder is a behavior-affecting refactor and explicitly OUT OF SCOPE for this no-behavior-change prerequisite PR. Suppression is added at the project level (NoWarn=ASPDEPR008 on Service.csproj + Service.Tests.csproj) with an inline TODO comment pointing at this branch and a follow-up issue link placeholder.

VALIDATION

dotnet --version : 10.0.301
dotnet restore --nologo : 11/11 projects restored
dotnet build -c Debug : 0 warnings, 0 errors

Multi-engine test categories (MsSql, PostgreSql, MySql, CosmosDb_NoSql, DwSql) were NOT run locally; they MUST run green on the Azure DevOps multi-engine matrix before this PR merges. That matrix is the gate.

NEXT STEPS BEFORE MERGE

  1. Release-engineering: refresh external_licenses/Microsoft.Data.SqlClient.SNI.6.0.2.License.txt from upstream for the SNI 6.0.2 version (currently still 5.2.0 text with a TODO marker at top).
  2. Release-engineering: confirm scripts/create-manifest-file.ps1 net10.0_{linux,win,osx}-x64 download URLs and SHA hashes resolve once the .NET 10 publish cycle runs.
  3. Multi-engine CI matrix runs green (MsSql, PostgreSql, MySql, CosmosDb_NoSql, DwSql) — that is the merge gate.
  4. File follow-up issue for ASPDEPR008 migration (WebHost -> WebApplicationBuilder / IHost) so the NoWarn suppressions can be removed in a future behavior-changing PR.
  5. File follow-up issue to evaluate Microsoft.Data.SqlClient 7.x (adds Microsoft.Data.SqlClient.Extensions.Azure, re-validate Entra ID / managed-identity auth).

Why make this change?

What is this change?

How was this tested?

  • Integration Tests (multi-engine CI matrix is the merge gate)
  • Unit Tests

Sample Request(s)

Joint runtime + driver bump that prerequisites issue #2768 (MSSQL JSON
data type support). Behavior-preserving — no production logic changes.

WHY BOTH BUMPS ARE REQUIRED TOGETHER
====================================

SqlDbType.Json (numeric value 35) is a BCL enum value in System.Data,
added in .NET 9 and present in .NET 10. It is NOT a Microsoft.Data.SqlClient
symbol — SqlClient does not get to add values to a BCL enum it does not
own. On .NET 8, the SqlDbType enum stops at DateTimeOffset = 34, so

    Enum.TryParse<SqlDbType>("json", ignoreCase: true, out _)

in TypeHelper.GetSystemTypeFromSqlDbType returns false regardless of
which SqlClient version is installed. The companion feature PR for #2768
plans to add a single dictionary entry

    [SqlDbType.Json] = typeof(string)

which simply will not compile on net8.0. Both upgrades must therefore
land together as a single prerequisite.

WHY .NET 10 AND NOT .NET 9
==========================

- .NET 10 is the current Long-Term Support release (Nov 2025+).
- .NET 9 is Standard-Term Support, EOL May 2026.
- DAB's current .NET 8 line reaches EOL November 2026.

Going straight to LTS avoids a second forced upgrade inside 12 months.

SCOPE OF CHANGES (NO BEHAVIOR CHANGE INTENDED)
==============================================

Runtime / SDK pin:
  - global.json: 8.0.420 -> 10.0.301

Target framework (all 11 src/**/*.csproj):
  - net8.0 -> net10.0

NuGet packages (Directory.Packages.props):
  - Microsoft.Data.SqlClient                    5.2.3  -> 6.0.2
  - Microsoft.Extensions.Caching.Memory         8.0.1  -> 10.0.0
  - Microsoft.Extensions.Caching.Abstractions   9.0.0  -> 10.0.0
  - Microsoft.Extensions.Primitives             9.0.0  -> 10.0.0
  - Microsoft.Extensions.Configuration.Binder   9.0.0  -> 10.0.0
  - Microsoft.Extensions.Configuration.Json     9.0.0  -> 10.0.0
  - Microsoft.Extensions.Caching.StackExchangeRedis 9.0.3 -> 10.0.0

The Microsoft.Extensions.* bumps are required because OpenTelemetry's
transitive chain (Microsoft.Extensions.Logging.Configuration 10.0.0)
demands Configuration.Binder >= 10.0.0 — staying on 9.0.0 produces
NU1605 package-downgrade errors (warning-as-error).

Service.csproj (Microsoft.NET.Sdk.Web) — drop now-redundant
PackageReferences (NU1510, warning-as-error):
  - Microsoft.Extensions.Configuration.Binder  (in shared framework)
  - Microsoft.Extensions.Configuration.Json    (in shared framework)

Azure DevOps pipelines (9 occurrences across 8 files):
  - UseDotNet@2 version: 8.0.x -> 10.0.x

Container base images (Dockerfile):
  - mcr.microsoft.com/dotnet/sdk:8.0-cbl-mariner2.0   -> 10.0-azurelinux3.0
  - mcr.microsoft.com/dotnet/aspnet:8.0-cbl-mariner2.0 -> 10.0-azurelinux3.0
  (cbl-mariner2.0 tag does not exist for .NET 9+; Azure Linux 3.0 is
   Microsoft's documented successor.)

Aspire AppHost (src/Aspire.AppHost/AppHost.cs):
  - WithArgs("-f", "net8.0") -> WithArgs("-f", "net10.0")  (mssql + pg)

Build/publish scripts:
  - scripts/publish.ps1:               $dotnetTargetFrameworks net8.0 -> net10.0
  - scripts/create-manifest-file.ps1:  $dotnetTargetFrameworks + hashtable
                                       keys net8.0_{rid} -> net10.0_{rid}
                                       (TODO marker: release-engineering to
                                       confirm download URLs/hashes resolve)

License file rename:
  - external_licenses/Microsoft.Data.SqlClient.SNI.5.2.0.License.txt
    -> external_licenses/Microsoft.Data.SqlClient.SNI.6.0.0.License.txt
  - scripts/notice-generation.ps1: path updated to match
  - TODO marker at top of license file: contents still 5.2.0 text;
    release-engineering to refresh from upstream before merge.

SUPPRESSED ASPDEPR008 (warning-as-error) — DELIBERATE
=====================================================

ASP.NET Core 10 deprecates IWebHostBuilder / IWebHost in favor of
WebApplicationBuilder / IHost. Two locations in this repo still consume
the obsolete types and would block compilation under the repo's
TreatWarningsAsErrors=true setting:

  - src/Service/Program.cs (2 sites): test-only helpers
    CreateWebHostBuilder + CreateWebHostFromInMemoryUpdatableConfBuilder
    are consumed by the existing TestServer fixture which takes
    IWebHostBuilder.
  - src/Service.Tests/Configuration/ConfigurationTests.cs (3 sites):
    the consumer of those helpers.

Migrating from WebHost to HostBuilder/WebApplicationBuilder is a
behavior-affecting refactor and explicitly OUT OF SCOPE for this
no-behavior-change prerequisite PR. Suppression is added at the
project level (NoWarn=ASPDEPR008 on Service.csproj + Service.Tests.csproj)
with an inline TODO comment pointing at this branch and a follow-up
issue link placeholder.

VALIDATION
==========

dotnet --version          : 10.0.301
dotnet restore --nologo   : 11/11 projects restored (8.05s avg)
dotnet build  -c Debug    : 0 warnings, 0 errors, 10.32s

Multi-engine test categories (MsSql, PostgreSql, MySql, CosmosDb_NoSql,
DwSql) were NOT run locally; they MUST run green on the Azure DevOps
multi-engine matrix before this PR merges. That matrix is the gate.

NEXT STEPS BEFORE MERGE
=======================

1. Release-engineering: refresh
   external_licenses/Microsoft.Data.SqlClient.SNI.6.0.0.License.txt
   from upstream for the SNI 6.0.0 version (currently still 5.2.0 text
   with a TODO marker at top).
2. Release-engineering: confirm
   scripts/create-manifest-file.ps1 net10.0_{linux,win,osx}-x64 download
   URLs and SHA hashes resolve once the .NET 10 publish cycle runs.
3. Multi-engine CI matrix runs green (MsSql, PostgreSql, MySql,
   CosmosDb_NoSql, DwSql) — that is the merge gate.
4. File follow-up issue for ASPDEPR008 migration (WebHost ->
   WebApplicationBuilder / IHost) so the NoWarn suppressions can be
   removed in a future behavior-changing PR.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 upgrades Data API Builder’s build/runtime baseline to .NET 10 (SDK pin + project TFMs) and bumps Microsoft.Data.SqlClient to 6.x as a prerequisite for upcoming SQL JSON / vector datatype support that depends on SqlDbType.Json being present in the BCL.

Changes:

  • Pin SDK to .NET 10.0.301 and retarget all src/** projects from net8.0 to net10.0.
  • Update central package versions (notably Microsoft.Data.SqlClient 6.0.2 and required Microsoft.Extensions.* 10.0.0) and remove now-redundant Service package refs.
  • Update pipelines/scripts/container images to build with .NET 10 and adjust ancillary release/notice assets (including SNI license file rename).

Reviewed changes

Copilot reviewed 27 out of 27 changed files in this pull request and generated 12 comments.

Show a summary per file
File Description
global.json Pins repo SDK to 10.0.301.
src/Service/Azure.DataApiBuilder.Service.csproj Retarget to net10.0, add ASPDEPR008 suppression, remove redundant config package refs.
src/Service.Tests/Azure.DataApiBuilder.Service.Tests.csproj Retarget tests to net10.0, add ASPDEPR008 suppression.
src/Core/Azure.DataApiBuilder.Core.csproj Retarget core library to net10.0.
src/Config/Azure.DataApiBuilder.Config.csproj Retarget config library to net10.0.
src/Auth/Azure.DataApiBuilder.Auth.csproj Retarget auth library to net10.0.
src/Cli/Cli.csproj Retarget CLI to net10.0.
src/Cli.Tests/Cli.Tests.csproj Retarget CLI tests to net10.0.
src/Product/Azure.DataApiBuilder.Product.csproj Retarget product project to net10.0.
src/Service.GraphQLBuilder/Azure.DataApiBuilder.Service.GraphQLBuilder.csproj Retarget GraphQL builder to net10.0.
src/Azure.DataApiBuilder.Mcp/Azure.DataApiBuilder.Mcp.csproj Retarget MCP project to net10.0.
src/Aspire.AppHost/Aspire.AppHost.csproj Retarget Aspire AppHost to net10.0.
src/Aspire.AppHost/AppHost.cs Update AppHost args from net8.0 to net10.0.
src/Directory.Packages.props Bump SqlClient + required Microsoft.Extensions.* packages to 10/6.x.
Dockerfile Move SDK/runtime base images to .NET 10 Azure Linux tags.
scripts/publish.ps1 Update publish framework strings to net10.0.
scripts/create-manifest-file.ps1 Update manifest framework keys to net10.0_*.
scripts/notice-generation.ps1 Update SNI license file path for notice generation.
external_licenses/Microsoft.Data.SqlClient.SNI.6.0.0.License.txt Renamed SNI license file for SqlClient 6.x (currently includes a TODO marker).
.pipelines/templates/static-tools.yml UseDotNet version updated to 10.0.x.
.pipelines/templates/mssql-test-steps.yml UseDotNet version updated to 10.0.x.
.pipelines/templates/build-pipelines.yml UseDotNet version updated to 10.0.x.
.pipelines/pg-pipelines.yml UseDotNet version updated to 10.0.x.
.pipelines/mysql-pipelines.yml UseDotNet version updated to 10.0.x.
.pipelines/mssql-pipelines.yml UseDotNet version updated to 10.0.x.
.pipelines/dwsql-pipelines.yml UseDotNet version updated to 10.0.x (linux + windows jobs).
.pipelines/cosmos-pipelines.yml UseDotNet version updated to 10.0.x.
Comments suppressed due to low confidence (1)

external_licenses/Microsoft.Data.SqlClient.SNI.6.0.0.License.txt:5

  • This license file still contains a TODO marker stating the body is for SNI 5.2.0, not the updated 6.0.0 version. Shipping with an intentionally stale license text (and an in-file TODO note) is a compliance risk; the file should be refreshed from the upstream SNI 6.0.0 license source before merge.

Comment thread .pipelines/templates/static-tools.yml Outdated
Comment thread .pipelines/templates/mssql-test-steps.yml Outdated
Comment thread .pipelines/templates/build-pipelines.yml Outdated
Comment thread .pipelines/pg-pipelines.yml Outdated
Comment thread .pipelines/mysql-pipelines.yml Outdated
Comment thread .pipelines/dwsql-pipelines.yml Outdated
Comment thread .pipelines/cosmos-pipelines.yml Outdated
Comment thread src/Service/Azure.DataApiBuilder.Service.csproj Outdated
Comment thread src/Service.Tests/Azure.DataApiBuilder.Service.Tests.csproj Outdated
Comment thread scripts/create-manifest-file.ps1 Outdated
RubenCerna2079 and others added 4 commits June 17, 2026 17:29
- Fix UseDotNet displayName v8.0.x -> v10.0.x across pipeline files

- Replace internal branch-path TODOs with durable follow-up notes

- Rename SNI license to 6.0.2 (actual runtime version) and fix notice-generation reference

- Bump Microsoft.AspNetCore.{TestHost,Authorization,Authentication.JwtBearer,Mvc.Testing} to 10.0.0
Aspire.Hosting pulls MessagePack 2.5.192 transitively (via KubernetesClient), which has high-severity advisory GHSA-hv8m-jj95-wg3x (CVE-2026-48109). The repo treats NU1903 as error, failing restore. Pin to patched 2.5.301 via CPM and add a direct reference in Aspire.AppHost to force the transitive upgrade.
@souvikghosh04 souvikghosh04 marked this pull request as draft June 18, 2026 06:32
…or change

SqlClient 6.x changed the internal SqlError 9-parameter constructor: the
win32ErrorCode parameter is now Int32 (was UInt32 in 5.x), and there are now
multiple 9-parameter overloads. Select the constructor by exact parameter
types and pass (int)0 for win32ErrorCode so CreateSqlException works across
SqlClient versions.
Starting with .NET 10, setting an environment variable to an empty string
preserves it as an empty value instead of deleting it (which previously
surfaced here as null). This caused ValidateAspNetCoreUrls to treat an empty
ASPNETCORE_URLS as invalid and exit with error, a regression from .NET 8 where
an empty value was equivalent to unset. Explicitly treat an empty value as
valid (Kestrel falls back to default URLs), preserving the prior behavior.
Whitespace-only values remain invalid.
Comment thread scripts/create-manifest-file.ps1
Comment thread scripts/notice-generation.ps1
Comment thread Dockerfile
private const string SQLDBTYPE_RESOLUTION_ERROR = "failed to resolve to SqlDbType.";
private const string SQLDBTYPE_UNEXPECTED_RESOLUTION_ERROR = "should have resolved to a SqlDbType.";
private const string JSONDATATYPE_RESOLUTION_ERROR = "(when supported) should map to a system type and associated JsonDataType.";
private const string DBTYPE_RESOLUTION_ERROR = "(when supported) should map to a system type and associated DbType.";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why are we removing this constant?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

this is an unused variable which came as warning/error in the pipeline runs with the .Net 10 upgrade. we can remove this safely as its not used anywhere.
image

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I don't think it should be removed since as it says in the string it had. (when supported) so it is something that we will have to add again at some point.

Comment thread src/Core/Resolvers/Sql Query Structures/SqlUpdateQueryStructure.cs
These three files were modified by an earlier merge in a way unrelated to the
.NET 10 / SqlClient 6.x upgrade, reverting recent main formatting/cleanup:

- CLRtoJsonValueTypeUnitTests.cs: restore the DBTYPE_RESOLUTION_ERROR constant
  that was inadvertently removed.
- SqlUpdateQueryStructure.cs: restore main's formatting of the update-fields
  block.
- MutationEngineFactory.cs: restore main's version.

Restoring them to match main keeps this PR scoped to the upgrade and addresses
reviewer feedback (constant removal and formatting).
@souvikghosh04 souvikghosh04 marked this pull request as ready for review June 19, 2026 08:22
@souvikghosh04 souvikghosh04 moved this from In Progress to Review In Progress in Data API builder Jun 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: Review In Progress

Development

Successfully merging this pull request may close these issues.

Upgrade .Net and SQLClient to support JSON and Vector data types

4 participants