Repository: dotnet/efcore

Issue:
Introduce UseAzureSql/UseAzureSynapse as alternatives to UseSqlServer
We're increasingly seeing T-SQL divergence, where certain features are not available e.g. on Azure Synapse (e.g. #33555), and some features are only available Azure SQL (e.g. the new JSON type, the new vector search capabilities). To account for this divergence, we'll allow users to specify which database is being targeted by providing UseAzureSql/UseAzureSynapse alternatives to UseSqlServer.

Note: we'd need to duplicate all current variants of UseSqlServer.


Hints:
So given the following engine editions:

2 = Standard (For Standard, Web, and Business Intelligence.)
3 = Enterprise (For Evaluation, Developer, and Enterprise editions.)
4 = Express (For Express, Express with Tools, and Express with Advanced Services)
5 = SQL Database
6 = Azure Synapse Analytics
8 = Azure SQL Managed Instance
9 = Azure SQL Edge (For all editions of Azure SQL Edge)
11 = Azure Synapse serverless SQL pool

**UseSqlServer: 2, 3, 4, 8 (5, 9)**

**UseAzureSql: 5, 8** (8 depending on [Update policy](https://learn.microsoft.com/en-us/azure/azure-sql/managed-instance/update-policy?view=azuresql&tabs=azure-portal) - default is SQL Server 2022 compatibility)

**UseAzureSynapse: 6, 11**



@ErikEJ are you suggesting we auto-detect based on the engine queried from the database, or something similar? Or allow the user to specify the engine edition directly?
@roji No - just trying to clarify for myself (and maybe others) what the options will actually mean
@roji Just was made aware of [this](https://learn.microsoft.com/en-us/azure/azure-sql/managed-instance/update-policy?view=azuresql&tabs=azure-portal), affecting Azure SQL Managed Instance
@ErikEJ interesting, thanks - I wasn't aware of this... It seems to optionally bring SQL Managed Instance closer to SQL Azure in terms of the engine/features. Do you see this as changing the above proposal?
@roji Yeah, just got this in a newsletter, seems like a brand new thing. It does not affect the above proposal, but I have made some small opdates to my list above.
Removing the milestone and adding `needs-design` to revisit if we are doing the right thing here, and what the mappings should be.
Thank you so much for working on this issue - it will be very helpful to users of Azure Synapse like me!  The lack of support in Synapse for `ESCAPE` (in `LIKE` clauses) and `OFFSET` (for paging) make it harder to use EF for this particular variant of T-SQL.

Patch:
diff --git a/src/EFCore.SqlServer/Extensions/SqlServerDbContextOptionsBuilderExtensions.cs b/src/EFCore.SqlServer/Extensions/SqlServerDbContextOptionsBuilderExtensions.cs
index 7214fd81382..5e5ecf8127d 100644
--- a/src/EFCore.SqlServer/Extensions/SqlServerDbContextOptionsBuilderExtensions.cs
+++ b/src/EFCore.SqlServer/Extensions/SqlServerDbContextOptionsBuilderExtensions.cs
@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 
 using Microsoft.EntityFrameworkCore.SqlServer.Infrastructure.Internal;
+using Microsoft.EntityFrameworkCore.SqlServer.Internal;
 
 // ReSharper disable once CheckNamespace
 namespace Microsoft.EntityFrameworkCore;
@@ -11,13 +12,13 @@ namespace Microsoft.EntityFrameworkCore;
 /// </summary>
 /// <remarks>
 ///     See <see href="https://aka.ms/efcore-docs-dbcontext-options">Using DbContextOptions</see>, and
-///     <see href="https://aka.ms/efcore-docs-sqlserver">Accessing SQL Server and Azure SQL databases with EF Core</see>
+///     <see href="https://aka.ms/efcore-docs-sqlserver">Accessing SQL Server, Azure SQL, Azure Synapse databases with EF Core</see>
 ///     for more information and examples.
 /// </remarks>
 public static class SqlServerDbContextOptionsExtensions
 {
     /// <summary>
-    ///     Configures the context to connect to a Microsoft SQL Server database, but without initially setting any
+    ///     Configures the context to connect to a SQL Server database, but without initially setting any
     ///     <see cref="DbConnection" /> or connection string.
     /// </summary>
     /// <remarks>
@@ -28,52 +29,56 @@ public static class SqlServerDbContextOptionsExtensions
     ///     </para>
     ///     <para>
     ///         See <see href="https://aka.ms/efcore-docs-dbcontext-options">Using DbContextOptions</see>, and
-    ///         <see href="https://aka.ms/efcore-docs-sqlserver">Accessing SQL Server and Azure SQL databases with EF Core</see>
+    ///         <see href="https://aka.ms/efcore-docs-sqlserver">Accessing SQL Server, Azure SQL, Azure Synapse databases with EF Core</see>
     ///         for more information and examples.
     ///     </para>
     /// </remarks>
     /// <param name="optionsBuilder">The builder being used to configure the context.</param>
-    /// <param name="sqlServerOptionsAction">An optional action to allow additional SQL Server specific configuration.</param>
+    /// <param name="sqlServerOptionsAction">An optional action to allow additional SQL Server, Azure SQL, Azure Synapse specific configuration.</param>
     /// <returns>The options builder so that further configuration can be chained.</returns>
     public static DbContextOptionsBuilder UseSqlServer(
         this DbContextOptionsBuilder optionsBuilder,
         Action<SqlServerDbContextOptionsBuilder>? sqlServerOptionsAction = null)
     {
-        ((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(GetOrCreateExtension(optionsBuilder));
-
+        var extension = GetOrCreateExtension<SqlServerOptionsExtension>(optionsBuilder);
+        extension = extension
+            .WithEngineType(SqlServerEngineType.SqlServer);
+        ((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);
         return ApplyConfiguration(optionsBuilder, sqlServerOptionsAction);
     }
 
     /// <summary>
-    ///     Configures the context to connect to a Microsoft SQL Server database.
+    ///     Configures the context to connect to a SQL Server database.
     /// </summary>
     /// <remarks>
     ///     See <see href="https://aka.ms/efcore-docs-dbcontext-options">Using DbContextOptions</see>, and
-    ///     <see href="https://aka.ms/efcore-docs-sqlserver">Accessing SQL Server and Azure SQL databases with EF Core</see>
+    ///     <see href="https://aka.ms/efcore-docs-sqlserver">Accessing SQL Server, Azure SQL, Azure Synapse databases with EF Core</see>
     ///     for more information and examples.
     /// </remarks>
     /// <param name="optionsBuilder">The builder being used to configure the context.</param>
     /// <param name="connectionString">The connection string of the database to connect to.</param>
-    /// <param name="sqlServerOptionsAction">An optional action to allow additional SQL Server specific configuration.</param>
+    /// <param name="sqlServerOptionsAction">An optional action to allow additional SQL Server, Azure SQL, Azure Synapse specific configuration.</param>
     /// <returns>The options builder so that further configuration can be chained.</returns>
     public static DbContextOptionsBuilder UseSqlServer(
         this DbContextOptionsBuilder optionsBuilder,
         string? connectionString,
         Action<SqlServerDbContextOptionsBuilder>? sqlServerOptionsAction = null)
     {
-        var extension = (SqlServerOptionsExtension)GetOrCreateExtension(optionsBuilder).WithConnectionString(connectionString);
+        var extension = GetOrCreateExtension<SqlServerOptionsExtension>(optionsBuilder);
+        extension = (SqlServerOptionsExtension)extension
+            .WithEngineType(SqlServerEngineType.SqlServer)
+            .WithConnectionString(connectionString);
         ((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);
-
         return ApplyConfiguration(optionsBuilder, sqlServerOptionsAction);
     }
 
     // Note: Decision made to use DbConnection not SqlConnection: Issue #772
     /// <summary>
-    ///     Configures the context to connect to a Microsoft SQL Server database.
+    ///     Configures the context to connect to a SQL Server database.
     /// </summary>
     /// <remarks>
     ///     See <see href="https://aka.ms/efcore-docs-dbcontext-options">Using DbContextOptions</see>, and
-    ///     <see href="https://aka.ms/efcore-docs-sqlserver">Accessing SQL Server and Azure SQL databases with EF Core</see>
+    ///     <see href="https://aka.ms/efcore-docs-sqlserver">Accessing SQL Server, Azure SQL, Azure Synapse databases with EF Core</see>
     ///     for more information and examples.
     /// </remarks>
     /// <param name="optionsBuilder">The builder being used to configure the context.</param>
@@ -83,7 +88,7 @@ public static DbContextOptionsBuilder UseSqlServer(
     ///     state then EF will open and close the connection as needed. The caller owns the connection and is
     ///     responsible for its disposal.
     /// </param>
-    /// <param name="sqlServerOptionsAction">An optional action to allow additional SQL Server specific configuration.</param>
+    /// <param name="sqlServerOptionsAction">An optional action to allow additional SQL Server, Azure SQL, Azure Synapse specific configuration.</param>
     /// <returns>The options builder so that further configuration can be chained.</returns>
     public static DbContextOptionsBuilder UseSqlServer(
         this DbContextOptionsBuilder optionsBuilder,
@@ -93,11 +98,11 @@ public static DbContextOptionsBuilder UseSqlServer(
 
     // Note: Decision made to use DbConnection not SqlConnection: Issue #772
     /// <summary>
-    ///     Configures the context to connect to a Microsoft SQL Server database.
+    ///     Configures the context to connect to a SQL Server database.
     /// </summary>
     /// <remarks>
     ///     See <see href="https://aka.ms/efcore-docs-dbcontext-options">Using DbContextOptions</see>, and
-    ///     <see href="https://aka.ms/efcore-docs-sqlserver">Accessing SQL Server and Azure SQL databases with EF Core</see>
+    ///     <see href="https://aka.ms/efcore-docs-sqlserver">Accessing SQL Server, Azure SQL, Azure Synapse databases with EF Core</see>
     ///     for more information and examples.
     /// </remarks>
     /// <param name="optionsBuilder">The builder being used to configure the context.</param>
@@ -111,7 +116,7 @@ public static DbContextOptionsBuilder UseSqlServer(
     ///     dispose it in the same way it would dispose a connection created by EF. If <see langword="false" />, then the caller still
     ///     owns the connection and is responsible for its disposal.
     /// </param>
-    /// <param name="sqlServerOptionsAction">An optional action to allow additional SQL Server specific configuration.</param>
+    /// <param name="sqlServerOptionsAction">An optional action to allow additional SQL Server, Azure SQL, Azure Synapse specific configuration.</param>
     /// <returns>The options builder so that further configuration can be chained.</returns>
     public static DbContextOptionsBuilder UseSqlServer(
         this DbContextOptionsBuilder optionsBuilder,
@@ -121,14 +126,16 @@ public static DbContextOptionsBuilder UseSqlServer(
     {
         Check.NotNull(connection, nameof(connection));
 
-        var extension = (SqlServerOptionsExtension)GetOrCreateExtension(optionsBuilder).WithConnection(connection, contextOwnsConnection);
+        var extension = GetOrCreateExtension<SqlServerOptionsExtension>(optionsBuilder);
+        extension = (SqlServerOptionsExtension)extension
+            .WithEngineType(SqlServerEngineType.SqlServer)
+            .WithConnection(connection, contextOwnsConnection);
         ((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);
-
         return ApplyConfiguration(optionsBuilder, sqlServerOptionsAction);
     }
 
     /// <summary>
-    ///     Configures the context to connect to a Microsoft SQL Server database, but without initially setting any
+    ///     Configures the context to connect to a SQL Server database, but without initially setting any
     ///     <see cref="DbConnection" /> or connection string.
     /// </summary>
     /// <remarks>
@@ -139,12 +146,12 @@ public static DbContextOptionsBuilder UseSqlServer(
     ///     </para>
     ///     <para>
     ///         See <see href="https://aka.ms/efcore-docs-dbcontext-options">Using DbContextOptions</see>, and
-    ///         <see href="https://aka.ms/efcore-docs-sqlserver">Accessing SQL Server and Azure SQL databases with EF Core</see>
+    ///         <see href="https://aka.ms/efcore-docs-sqlserver">Accessing SQL Server, Azure SQL, Azure Synapse databases with EF Core</see>
     ///         for more information and examples.
     ///     </para>
     /// </remarks>
     /// <param name="optionsBuilder">The builder being used to configure the context.</param>
-    /// <param name="sqlServerOptionsAction">An optional action to allow additional SQL Server specific configuration.</param>
+    /// <param name="sqlServerOptionsAction">An optional action to allow additional SQL Server, Azure SQL, Azure Synapse specific configuration.</param>
     /// <returns>The options builder so that further configuration can be chained.</returns>
     public static DbContextOptionsBuilder<TContext> UseSqlServer<TContext>(
         this DbContextOptionsBuilder<TContext> optionsBuilder,
@@ -154,17 +161,17 @@ public static DbContextOptionsBuilder<TContext> UseSqlServer<TContext>(
             (DbContextOptionsBuilder)optionsBuilder, sqlServerOptionsAction);
 
     /// <summary>
-    ///     Configures the context to connect to a Microsoft SQL Server database.
+    ///     Configures the context to connect to a SQL Server database.
     /// </summary>
     /// <remarks>
     ///     See <see href="https://aka.ms/efcore-docs-dbcontext-options">Using DbContextOptions</see>, and
-    ///     <see href="https://aka.ms/efcore-docs-sqlserver">Accessing SQL Server and Azure SQL databases with EF Core</see>
+    ///     <see href="https://aka.ms/efcore-docs-sqlserver">Accessing SQL Server, Azure SQL, Azure Synapse databases with EF Core</see>
     ///     for more information and examples.
     /// </remarks>
     /// <typeparam name="TContext">The type of context to be configured.</typeparam>
     /// <param name="optionsBuilder">The builder being used to configure the context.</param>
     /// <param name="connectionString">The connection string of the database to connect to.</param>
-    /// <param name="sqlServerOptionsAction">An optional action to allow additional SQL Server specific configuration.</param>
+    /// <param name="sqlServerOptionsAction">An optional action to allow additional SQL Server, Azure SQL, Azure Synapse specific configuration.</param>
     /// <returns>The options builder so that further configuration can be chained.</returns>
     public static DbContextOptionsBuilder<TContext> UseSqlServer<TContext>(
         this DbContextOptionsBuilder<TContext> optionsBuilder,
@@ -176,11 +183,11 @@ public static DbContextOptionsBuilder<TContext> UseSqlServer<TContext>(
 
     // Note: Decision made to use DbConnection not SqlConnection: Issue #772
     /// <summary>
-    ///     Configures the context to connect to a Microsoft SQL Server database.
+    ///     Configures the context to connect to a SQL Server database.
     /// </summary>
     /// <remarks>
     ///     See <see href="https://aka.ms/efcore-docs-dbcontext-options">Using DbContextOptions</see>, and
-    ///     <see href="https://aka.ms/efcore-docs-sqlserver">Accessing SQL Server and Azure SQL databases with EF Core</see>
+    ///     <see href="https://aka.ms/efcore-docs-sqlserver">Accessing SQL Server, Azure SQL, Azure Synapse databases with EF Core</see>
     ///     for more information and examples.
     /// </remarks>
     /// <typeparam name="TContext">The type of context to be configured.</typeparam>
@@ -191,7 +198,7 @@ public static DbContextOptionsBuilder<TContext> UseSqlServer<TContext>(
     ///     state then EF will open and close the connection as needed. The caller owns the connection and is
     ///     responsible for its disposal.
     /// </param>
-    /// <param name="sqlServerOptionsAction">An optional action to allow additional SQL Server specific configuration.</param>
+    /// <param name="sqlServerOptionsAction">An optional action to allow additional SQL Server, Azure SQL, Azure Synapse specific configuration.</param>
     /// <returns>The options builder so that further configuration can be chained.</returns>
     public static DbContextOptionsBuilder<TContext> UseSqlServer<TContext>(
         this DbContextOptionsBuilder<TContext> optionsBuilder,
@@ -203,11 +210,11 @@ public static DbContextOptionsBuilder<TContext> UseSqlServer<TContext>(
 
     // Note: Decision made to use DbConnection not SqlConnection: Issue #772
     /// <summary>
-    ///     Configures the context to connect to a Microsoft SQL Server database.
+    ///     Configures the context to connect to a SQL Server database.
     /// </summary>
     /// <remarks>
     ///     See <see href="https://aka.ms/efcore-docs-dbcontext-options">Using DbContextOptions</see>, and
-    ///     <see href="https://aka.ms/efcore-docs-sqlserver">Accessing SQL Server and Azure SQL databases with EF Core</see>
+    ///     <see href="https://aka.ms/efcore-docs-sqlserver">Accessing SQL Server, Azure SQL, Azure Synapse databases with EF Core</see>
     ///     for more information and examples.
     /// </remarks>
     /// <typeparam name="TContext">The type of context to be configured.</typeparam>
@@ -222,7 +229,7 @@ public static DbContextOptionsBuilder<TContext> UseSqlServer<TContext>(
     ///     dispose it in the same way it would dispose a connection created by EF. If <see langword="false" />, then the caller still
     ///     owns the connection and is responsible for its disposal.
     /// </param>
-    /// <param name="sqlServerOptionsAction">An optional action to allow additional SQL Server specific configuration.</param>
+    /// <param name="sqlServerOptionsAction">An optional action to allow additional SQL Server, Azure SQL, Azure Synapse specific configuration.</param>
     /// <returns>The options builder so that further configuration can be chained.</returns>
     public static DbContextOptionsBuilder<TContext> UseSqlServer<TContext>(
         this DbContextOptionsBuilder<TContext> optionsBuilder,
@@ -233,9 +240,509 @@ public static DbContextOptionsBuilder<TContext> UseSqlServer<TContext>(
         => (DbContextOptionsBuilder<TContext>)UseSqlServer(
             (DbContextOptionsBuilder)optionsBuilder, connection, contextOwnsConnection, sqlServerOptionsAction);
 
-    private static SqlServerOptionsExtension GetOrCreateExtension(DbContextOptionsBuilder optionsBuilder)
-        => optionsBuilder.Options.FindExtension<SqlServerOptionsExtension>()
-            ?? new SqlServerOptionsExtension();
+    /// <summary>
+    ///     Configures the context to connect to a Azure SQL database, but without initially setting any
+    ///     <see cref="DbConnection" /> or connection string.
+    /// </summary>
+    /// <remarks>
+    ///     <para>
+    ///         The connection or connection string must be set before the <see cref="DbContext" /> is used to connect
+    ///         to a database. Set a connection using <see cref="RelationalDatabaseFacadeExtensions.SetDbConnection" />.
+    ///         Set a connection string using <see cref="RelationalDatabaseFacadeExtensions.SetConnectionString" />.
+    ///     </para>
+    ///     <para>
+    ///         See <see href="https://aka.ms/efcore-docs-dbcontext-options">Using DbContextOptions</see>, and
+    ///         <see href="https://aka.ms/efcore-docs-sqlserver">Accessing SQL Server, Azure SQL, Azure Synapse databases with EF Core</see>
+    ///         for more information and examples.
+    ///     </para>
+    /// </remarks>
+    /// <param name="optionsBuilder">The builder being used to configure the context.</param>
+    /// <param name="sqlServerOptionsAction">An optional action to allow additional SQL Server, Azure SQL, Azure Synapse specific configuration.</param>
+    /// <returns>The options builder so that further configuration can be chained.</returns>
+    public static DbContextOptionsBuilder UseAzureSql(
+        this DbContextOptionsBuilder optionsBuilder,
+        Action<SqlServerDbContextOptionsBuilder>? sqlServerOptionsAction = null)
+    {
+        var extension = GetOrCreateExtension<SqlServerOptionsExtension>(optionsBuilder);
+        extension = extension
+            .WithEngineType(SqlServerEngineType.AzureSql);
+        ((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);
+        return ApplyConfiguration(optionsBuilder, sqlServerOptionsAction);
+    }
+
+    /// <summary>
+    ///     Configures the context to connect to a Azure SQL database.
+    /// </summary>
+    /// <remarks>
+    ///     See <see href="https://aka.ms/efcore-docs-dbcontext-options">Using DbContextOptions</see>, and
+    ///     <see href="https://aka.ms/efcore-docs-sqlserver">Accessing SQL Server, Azure SQL, Azure Synapse databases with EF Core</see>
+    ///     for more information and examples.
+    /// </remarks>
+    /// <param name="optionsBuilder">The builder being used to configure the context.</param>
+    /// <param name="connectionString">The connection string of the database to connect to.</param>
+    /// <param name="sqlServerOptionsAction">An optional action to allow additional SQL Server, Azure SQL, Azure Synapse specific configuration.</param>
+    /// <returns>The options builder so that further configuration can be chained.</returns>
+    public static DbContextOptionsBuilder UseAzureSql(
+        this DbContextOptionsBuilder optionsBuilder,
+        string? connectionString,
+        Action<SqlServerDbContextOptionsBuilder>? sqlServerOptionsAction = null)
+    {
+        var extension = GetOrCreateExtension<SqlServerOptionsExtension>(optionsBuilder);
+        extension = (SqlServerOptionsExtension)extension
+            .WithEngineType(SqlServerEngineType.AzureSql)
+            .WithConnectionString(connectionString);
+        ((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);
+        return ApplyConfiguration(optionsBuilder, sqlServerOptionsAction);
+    }
+
+    // Note: Decision made to use DbConnection not SqlConnection: Issue #772
+    /// <summary>
+    ///     Configures the context to connect to a Azure SQL database.
+    /// </summary>
+    /// <remarks>
+    ///     See <see href="https://aka.ms/efcore-docs-dbcontext-options">Using DbContextOptions</see>, and
+    ///     <see href="https://aka.ms/efcore-docs-sqlserver">Accessing SQL Server, Azure SQL, Azure Synapse databases with EF Core</see>
+    ///     for more information and examples.
+    /// </remarks>
+    /// <param name="optionsBuilder">The builder being used to configure the context.</param>
+    /// <param name="connection">
+    ///     An existing <see cref="DbConnection" /> to be used to connect to the database. If the connection is
+    ///     in the open state then EF will not open or close the connection. If the connection is in the closed
+    ///     state then EF will open and close the connection as needed. The caller owns the connection and is
+    ///     responsible for its disposal.
+    /// </param>
+    /// <param name="sqlServerOptionsAction">An optional action to allow additional SQL Server, Azure SQL, Azure Synapse specific configuration.</param>
+    /// <returns>The options builder so that further configuration can be chained.</returns>
+    public static DbContextOptionsBuilder UseAzureSql(
+        this DbContextOptionsBuilder optionsBuilder,
+        DbConnection connection,
+        Action<SqlServerDbContextOptionsBuilder>? sqlServerOptionsAction = null)
+        => UseAzureSql(optionsBuilder, connection, false, sqlServerOptionsAction);
+
+    // Note: Decision made to use DbConnection not SqlConnection: Issue #772
+    /// <summary>
+    ///     Configures the context to connect to a Azure SQL database.
+    /// </summary>
+    /// <remarks>
+    ///     See <see href="https://aka.ms/efcore-docs-dbcontext-options">Using DbContextOptions</see>, and
+    ///     <see href="https://aka.ms/efcore-docs-sqlserver">Accessing SQL Server, Azure SQL, Azure Synapse databases with EF Core</see>
+    ///     for more information and examples.
+    /// </remarks>
+    /// <param name="optionsBuilder">The builder being used to configure the context.</param>
+    /// <param name="connection">
+    ///     An existing <see cref="DbConnection" /> to be used to connect to the database. If the connection is
+    ///     in the open state then EF will not open or close the connection. If the connection is in the closed
+    ///     state then EF will open and close the connection as needed.
+    /// </param>
+    /// <param name="contextOwnsConnection">
+    ///     If <see langword="true" />, then EF will take ownership of the connection and will
+    ///     dispose it in the same way it would dispose a connection created by EF. If <see langword="false" />, then the caller still
+    ///     owns the connection and is responsible for its disposal.
+    /// </param>
+    /// <param name="sqlServerOptionsAction">An optional action to allow additional SQL Server, Azure SQL, Azure Synapse specific configuration.</param>
+    /// <returns>The options builder so that further configuration can be chained.</returns>
+    public static DbContextOptionsBuilder UseAzureSql(
+        this DbContextOptionsBuilder optionsBuilder,
+        DbConnection connection,
+        bool contextOwnsConnection,
+        Action<SqlServerDbContextOptionsBuilder>? sqlServerOptionsAction = null)
+    {
+        Check.NotNull(connection, nameof(connection));
+
+        var extension = GetOrCreateExtension<SqlServerOptionsExtension>(optionsBuilder);
+        extension = (SqlServerOptionsExtension)extension
+            .WithEngineType(SqlServerEngineType.AzureSql)
+            .WithConnection(connection, contextOwnsConnection);
+        ((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);
+        return ApplyConfiguration(optionsBuilder, sqlServerOptionsAction);
+    }
+
+    /// <summary>
+    ///     Configures the context to connect to a Azure SQL database, but without initially setting any
+    ///     <see cref="DbConnection" /> or connection string.
+    /// </summary>
+    /// <remarks>
+    ///     <para>
+    ///         The connection or connection string must be set before the <see cref="DbContext" /> is used to connect
+    ///         to a database. Set a connection using <see cref="RelationalDatabaseFacadeExtensions.SetDbConnection" />.
+    ///         Set a connection string using <see cref="RelationalDatabaseFacadeExtensions.SetConnectionString" />.
+    ///     </para>
+    ///     <para>
+    ///         See <see href="https://aka.ms/efcore-docs-dbcontext-options">Using DbContextOptions</see>, and
+    ///         <see href="https://aka.ms/efcore-docs-sqlserver">Accessing SQL Server, Azure SQL, Azure Synapse databases with EF Core</see>
+    ///         for more information and examples.
+    ///     </para>
+    /// </remarks>
+    /// <param name="optionsBuilder">The builder being used to configure the context.</param>
+    /// <param name="sqlServerOptionsAction">An optional action to allow additional SQL Server, Azure SQL, Azure Synapse specific configuration.</param>
+    /// <returns>The options builder so that further configuration can be chained.</returns>
+    public static DbContextOptionsBuilder<TContext> UseAzureSql<TContext>(
+        this DbContextOptionsBuilder<TContext> optionsBuilder,
+        Action<SqlServerDbContextOptionsBuilder>? sqlServerOptionsAction = null)
+        where TContext : DbContext
+        => (DbContextOptionsBuilder<TContext>)UseAzureSql(
+            (DbContextOptionsBuilder)optionsBuilder, sqlServerOptionsAction);
+
+    /// <summary>
+    ///     Configures the context to connect to a Azure SQL database.
+    /// </summary>
+    /// <remarks>
+    ///     See <see href="https://aka.ms/efcore-docs-dbcontext-options">Using DbContextOptions</see>, and
+    ///     <see href="https://aka.ms/efcore-docs-sqlserver">Accessing SQL Server, Azure SQL, Azure Synapse databases with EF Core</see>
+    ///     for more information and examples.
+    /// </remarks>
+    /// <typeparam name="TContext">The type of context to be configured.</typeparam>
+    /// <param name="optionsBuilder">The builder being used to configure the context.</param>
+    /// <param name="connectionString">The connection string of the database to connect to.</param>
+    /// <param name="sqlServerOptionsAction">An optional action to allow additional SQL Server, Azure SQL, Azure Synapse specific configuration.</param>
+    /// <returns>The options builder so that further configuration can be chained.</returns>
+    public static DbContextOptionsBuilder<TContext> UseAzureSql<TContext>(
+        this DbContextOptionsBuilder<TContext> optionsBuilder,
+        string? connectionString,
+        Action<SqlServerDbContextOptionsBuilder>? sqlServerOptionsAction = null)
+        where TContext : DbContext
+        => (DbContextOptionsBuilder<TContext>)UseAzureSql(
+            (DbContextOptionsBuilder)optionsBuilder, connectionString, sqlServerOptionsAction);
+
+    // Note: Decision made to use DbConnection not SqlConnection: Issue #772
+    /// <summary>
+    ///     Configures the context to connect to a Azure SQL database.
+    /// </summary>
+    /// <remarks>
+    ///     See <see href="https://aka.ms/efcore-docs-dbcontext-options">Using DbContextOptions</see>, and
+    ///     <see href="https://aka.ms/efcore-docs-sqlserver">Accessing SQL Server, Azure SQL, Azure Synapse databases with EF Core</see>
+    ///     for more information and examples.
+    /// </remarks>
+    /// <typeparam name="TContext">The type of context to be configured.</typeparam>
+    /// <param name="optionsBuilder">The builder being used to configure the context.</param>
+    /// <param name="connection">
+    ///     An existing <see cref="DbConnection" /> to be used to connect to the database. If the connection is
+    ///     in the open state then EF will not open or close the connection. If the connection is in the closed
+    ///     state then EF will open and close the connection as needed. The caller owns the connection and is
+    ///     responsible for its disposal.
+    /// </param>
+    /// <param name="sqlServerOptionsAction">An optional action to allow additional SQL Server, Azure SQL, Azure Synapse specific configuration.</param>
+    /// <returns>The options builder so that further configuration can be chained.</returns>
+    public static DbContextOptionsBuilder<TContext> UseAzureSql<TContext>(
+        this DbContextOptionsBuilder<TContext> optionsBuilder,
+        DbConnection connection,
+        Action<SqlServerDbContextOptionsBuilder>? sqlServerOptionsAction = null)
+        where TContext : DbContext
+        => (DbContextOptionsBuilder<TContext>)UseAzureSql(
+            (DbContextOptionsBuilder)optionsBuilder, connection, sqlServerOptionsAction);
+
+    // Note: Decision made to use DbConnection not SqlConnection: Issue #772
+    /// <summary>
+    ///     Configures the context to connect to a Azure SQL database.
+    /// </summary>
+    /// <remarks>
+    ///     See <see href="https://aka.ms/efcore-docs-dbcontext-options">Using DbContextOptions</see>, and
+    ///     <see href="https://aka.ms/efcore-docs-sqlserver">Accessing SQL Server, Azure SQL, Azure Synapse databases with EF Core</see>
+    ///     for more information and examples.
+    /// </remarks>
+    /// <typeparam name="TContext">The type of context to be configured.</typeparam>
+    /// <param name="optionsBuilder">The builder being used to configure the context.</param>
+    /// <param name="connection">
+    ///     An existing <see cref="DbConnection" /> to be used to connect to the database. If the connection is
+    ///     in the open state then EF will not open or close the connection. If the connection is in the closed
+    ///     state then EF will open and close the connection as needed.
+    /// </param>
+    /// <param name="contextOwnsConnection">
+    ///     If <see langword="true" />, then EF will take ownership of the connection and will
+    ///     dispose it in the same way it would dispose a connection created by EF. If <see langword="false" />, then the caller still
+    ///     owns the connection and is responsible for its disposal.
+    /// </param>
+    /// <param name="sqlServerOptionsAction">An optional action to allow additional SQL Server, Azure SQL, Azure Synapse specific configuration.</param>
+    /// <returns>The options builder so that further configuration can be chained.</returns>
+    public static DbContextOptionsBuilder<TContext> UseAzureSql<TContext>(
+        this DbContextOptionsBuilder<TContext> optionsBuilder,
+        DbConnection connection,
+        bool contextOwnsConnection,
+        Action<SqlServerDbContextOptionsBuilder>? sqlServerOptionsAction = null)
+        where TContext : DbContext
+        => (DbContextOptionsBuilder<TContext>)UseAzureSql(
+            (DbContextOptionsBuilder)optionsBuilder, connection, contextOwnsConnection, sqlServerOptionsAction);
+
+    /// <summary>
+    ///     Configures the context to connect to a Azure Synapse database, but without initially setting any
+    ///     <see cref="DbConnection" /> or connection string.
+    /// </summary>
+    /// <remarks>
+    ///     <para>
+    ///         The connection or connection string must be set before the <see cref="DbContext" /> is used to connect
+    ///         to a database. Set a connection using <see cref="RelationalDatabaseFacadeExtensions.SetDbConnection" />.
+    ///         Set a connection string using <see cref="RelationalDatabaseFacadeExtensions.SetConnectionString" />.
+    ///     </para>
+    ///     <para>
+    ///         See <see href="https://aka.ms/efcore-docs-dbcontext-options">Using DbContextOptions</see>, and
+    ///         <see href="https://aka.ms/efcore-docs-sqlserver">Accessing SQL Server, Azure SQL, Azure Synapse databases with EF Core</see>
+    ///         for more information and examples.
+    ///     </para>
+    /// </remarks>
+    /// <param name="optionsBuilder">The builder being used to configure the context.</param>
+    /// <param name="sqlServerOptionsAction">An optional action to allow additional SQL Server, Azure SQL, Azure Synapse specific configuration.</param>
+    /// <returns>The options builder so that further configuration can be chained.</returns>
+    public static DbContextOptionsBuilder UseAzureSynapse(
+        this DbContextOptionsBuilder optionsBuilder,
+        Action<SqlServerDbContextOptionsBuilder>? sqlServerOptionsAction = null)
+    {
+        var extension = GetOrCreateExtension<SqlServerOptionsExtension>(optionsBuilder);
+        extension = extension
+            .WithEngineType(SqlServerEngineType.AzureSynapse);
+        ((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);
+        return ApplyConfiguration(optionsBuilder, sqlServerOptionsAction);
+    }
+
+    /// <summary>
+    ///     Configures the context to connect to a Azure Synapse database.
+    /// </summary>
+    /// <remarks>
+    ///     See <see href="https://aka.ms/efcore-docs-dbcontext-options">Using DbContextOptions</see>, and
+    ///     <see href="https://aka.ms/efcore-docs-sqlserver">Accessing SQL Server, Azure SQL, Azure Synapse databases with EF Core</see>
+    ///     for more information and examples.
+    /// </remarks>
+    /// <param name="optionsBuilder">The builder being used to configure the context.</param>
+    /// <param name="connectionString">The connection string of the database to connect to.</param>
+    /// <param name="sqlServerOptionsAction">An optional action to allow additional SQL Server, Azure SQL, Azure Synapse specific configuration.</param>
+    /// <returns>The options builder so that further configuration can be chained.</returns>
+    public static DbContextOptionsBuilder UseAzureSynapse(
+        this DbContextOptionsBuilder optionsBuilder,
+        string? connectionString,
+        Action<SqlServerDbContextOptionsBuilder>? sqlServerOptionsAction = null)
+    {
+        var extension = GetOrCreateExtension<SqlServerOptionsExtension>(optionsBuilder);
+        extension = (SqlServerOptionsExtension)extension
+            .WithEngineType(SqlServerEngineType.AzureSynapse)
+            .WithConnectionString(connectionString);
+        ((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);
+        return ApplyConfiguration(optionsBuilder, sqlServerOptionsAction);
+    }
+
+    // Note: Decision made to use DbConnection not SqlConnection: Issue #772
+    /// <summary>
+    ///     Configures the context to connect to a Azure Synapse database.
+    /// </summary>
+    /// <remarks>
+    ///     See <see href="https://aka.ms/efcore-docs-dbcontext-options">Using DbContextOptions</see>, and
+    ///     <see href="https://aka.ms/efcore-docs-sqlserver">Accessing SQL Server, Azure SQL, Azure Synapse databases with EF Core</see>
+    ///     for more information and examples.
+    /// </remarks>
+    /// <param name="optionsBuilder">The builder being used to configure the context.</param>
+    /// <param name="connection">
+    ///     An existing <see cref="DbConnection" /> to be used to connect to the database. If the connection is
+    ///     in the open state then EF will not open or close the connection. If the connection is in the closed
+    ///     state then EF will open and close the connection as needed. The caller owns the connection and is
+    ///     responsible for its disposal.
+    /// </param>
+    /// <param name="sqlServerOptionsAction">An optional action to allow additional SQL Server, Azure SQL, Azure Synapse specific configuration.</param>
+    /// <returns>The options builder so that further configuration can be chained.</returns>
+    public static DbContextOptionsBuilder UseAzureSynapse(
+        this DbContextOptionsBuilder optionsBuilder,
+        DbConnection connection,
+        Action<SqlServerDbContextOptionsBuilder>? sqlServerOptionsAction = null)
+        => UseAzureSynapse(optionsBuilder, connection, false, sqlServerOptionsAction);
+
+    // Note: Decision made to use DbConnection not SqlConnection: Issue #772
+    /// <summary>
+    ///     Configures the context to connect to a Azure Synapse database.
+    /// </summary>
+    /// <remarks>
+    ///     See <see href="https://aka.ms/efcore-docs-dbcontext-options">Using DbContextOptions</see>, and
+    ///     <see href="https://aka.ms/efcore-docs-sqlserver">Accessing SQL Server, Azure SQL, Azure Synapse databases with EF Core</see>
+    ///     for more information and examples.
+    /// </remarks>
+    /// <param name="optionsBuilder">The builder being used to configure the context.</param>
+    /// <param name="connection">
+    ///     An existing <see cref="DbConnection" /> to be used to connect to the database. If the connection is
+    ///     in the open state then EF will not open or close the connection. If the connection is in the closed
+    ///     state then EF will open and close the connection as needed.
+    /// </param>
+    /// <param name="contextOwnsConnection">
+    ///     If <see langword="true" />, then EF will take ownership of the connection and will
+    ///     dispose it in the same way it would dispose a connection created by EF. If <see langword="false" />, then the caller still
+    ///     owns the connection and is responsible for its disposal.
+    /// </param>
+    /// <param name="sqlServerOptionsAction">An optional action to allow additional SQL Server, Azure SQL, Azure Synapse specific configuration.</param>
+    /// <returns>The options builder so that further configuration can be chained.</returns>
+    public static DbContextOptionsBuilder UseAzureSynapse(
+        this DbContextOptionsBuilder optionsBuilder,
+        DbConnection connection,
+        bool contextOwnsConnection,
+        Action<SqlServerDbContextOptionsBuilder>? sqlServerOptionsAction = null)
+    {
+        Check.NotNull(connection, nameof(connection));
+
+        var extension = GetOrCreateExtension<SqlServerOptionsExtension>(optionsBuilder);
+        extension = (SqlServerOptionsExtension)extension
+            .WithEngineType(SqlServerEngineType.AzureSynapse)
+            .WithConnection(connection, contextOwnsConnection);
+        ((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);
+        return ApplyConfiguration(optionsBuilder, sqlServerOptionsAction);
+    }
+
+    /// <summary>
+    ///     Configures the context to connect to a Azure Synapse database, but without initially setting any
+    ///     <see cref="DbConnection" /> or connection string.
+    /// </summary>
+    /// <remarks>
+    ///     <para>
+    ///         The connection or connection string must be set before the <see cref="DbContext" /> is used to connect
+    ///         to a database. Set a connection using <see cref="RelationalDatabaseFacadeExtensions.SetDbConnection" />.
+    ///         Set a connection string using <see cref="RelationalDatabaseFacadeExtensions.SetConnectionString" />.
+    ///     </para>
+    ///     <para>
+    ///         See <see href="https://aka.ms/efcore-docs-dbcontext-options">Using DbContextOptions</see>, and
+    ///         <see href="https://aka.ms/efcore-docs-sqlserver">Accessing SQL Server, Azure SQL, Azure Synapse databases with EF Core</see>
+    ///         for more information and examples.
+    ///     </para>
+    /// </remarks>
+    /// <param name="optionsBuilder">The builder being used to configure the context.</param>
+    /// <param name="sqlServerOptionsAction">An optional action to allow additional SQL Server, Azure SQL, Azure Synapse specific configuration.</param>
+    /// <returns>The options builder so that further configuration can be chained.</returns>
+    public static DbContextOptionsBuilder<TContext> UseAzureSynapse<TContext>(
+        this DbContextOptionsBuilder<TContext> optionsBuilder,
+        Action<SqlServerDbContextOptionsBuilder>? sqlServerOptionsAction = null)
+        where TContext : DbContext
+        => (DbContextOptionsBuilder<TContext>)UseAzureSynapse(
+            (DbContextOptionsBuilder)optionsBuilder, sqlServerOptionsAction);
+
+    /// <summary>
+    ///     Configures the context to connect to a Azure Synapse database.
+    /// </summary>
+    /// <remarks>
+    ///     See <see href="https://aka.ms/efcore-docs-dbcontext-options">Using DbContextOptions</see>, and
+    ///     <see href="https://aka.ms/efcore-docs-sqlserver">Accessing SQL Server, Azure SQL, Azure Synapse databases with EF Core</see>
+    ///     for more information and examples.
+    /// </remarks>
+    /// <typeparam name="TContext">The type of context to be configured.</typeparam>
+    /// <param name="optionsBuilder">The builder being used to configure the context.</param>
+    /// <param name="connectionString">The connection string of the database to connect to.</param>
+    /// <param name="sqlServerOptionsAction">An optional action to allow additional SQL Server, Azure SQL, Azure Synapse specific configuration.</param>
+    /// <returns>The options builder so that further configuration can be chained.</returns>
+    public static DbContextOptionsBuilder<TContext> UseAzureSynapse<TContext>(
+        this DbContextOptionsBuilder<TContext> optionsBuilder,
+        string? connectionString,
+        Action<SqlServerDbContextOptionsBuilder>? sqlServerOptionsAction = null)
+        where TContext : DbContext
+        => (DbContextOptionsBuilder<TContext>)UseAzureSynapse(
+            (DbContextOptionsBuilder)optionsBuilder, connectionString, sqlServerOptionsAction);
+
+    // Note: Decision made to use DbConnection not SqlConnection: Issue #772
+    /// <summary>
+    ///     Configures the context to connect to a Azure Synapse database.
+    /// </summary>
+    /// <remarks>
+    ///     See <see href="https://aka.ms/efcore-docs-dbcontext-options">Using DbContextOptions</see>, and
+    ///     <see href="https://aka.ms/efcore-docs-sqlserver">Accessing SQL Server, Azure SQL, Azure Synapse databases with EF Core</see>
+    ///     for more information and examples.
+    /// </remarks>
+    /// <typeparam name="TContext">The type of context to be configured.</typeparam>
+    /// <param name="optionsBuilder">The builder being used to configure the context.</param>
+    /// <param name="connection">
+    ///     An existing <see cref="DbConnection" /> to be used to connect to the database. If the connection is
+    ///     in the open state then EF will not open or close the connection. If the connection is in the closed
+    ///     state then EF will open and close the connection as needed. The caller owns the connection and is
+    ///     responsible for its disposal.
+    /// </param>
+    /// <param name="sqlServerOptionsAction">An optional action to allow additional SQL Server, Azure SQL, Azure Synapse specific configuration.</param>
+    /// <returns>The options builder so that further configuration can be chained.</returns>
+    public static DbContextOptionsBuilder<TContext> UseAzureSynapse<TContext>(
+        this DbContextOptionsBuilder<TContext> optionsBuilder,
+        DbConnection connection,
+        Action<SqlServerDbContextOptionsBuilder>? sqlServerOptionsAction = null)
+        where TContext : DbContext
+        => (DbContextOptionsBuilder<TContext>)UseAzureSynapse(
+            (DbContextOptionsBuilder)optionsBuilder, connection, sqlServerOptionsAction);
+
+    // Note: Decision made to use DbConnection not SqlConnection: Issue #772
+    /// <summary>
+    ///     Configures the context to connect to a Azure Synapse database.
+    /// </summary>
+    /// <remarks>
+    ///     See <see href="https://aka.ms/efcore-docs-dbcontext-options">Using DbContextOptions</see>, and
+    ///     <see href="https://aka.ms/efcore-docs-sqlserver">Accessing SQL Server, Azure SQL, Azure Synapse databases with EF Core</see>
+    ///     for more information and examples.
+    /// </remarks>
+    /// <typeparam name="TContext">The type of context to be configured.</typeparam>
+    /// <param name="optionsBuilder">The builder being used to configure the context.</param>
+    /// <param name="connection">
+    ///     An existing <see cref="DbConnection" /> to be used to connect to the database. If the connection is
+    ///     in the open state then EF will not open or close the connection. If the connection is in the closed
+    ///     state then EF will open and close the connection as needed.
+    /// </param>
+    /// <param name="contextOwnsConnection">
+    ///     If <see langword="true" />, then EF will take ownership of the connection and will
+    ///     dispose it in the same way it would dispose a connection created by EF. If <see langword="false" />, then the caller still
+    ///     owns the connection and is responsible for its disposal.
+    /// </param>
+    /// <param name="sqlServerOptionsAction">An optional action to allow additional SQL Server, Azure SQL, Azure Synapse specific configuration.</param>
+    /// <returns>The options builder so that further configuration can be chained.</returns>
+    public static DbContextOptionsBuilder<TContext> UseAzureSynapse<TContext>(
+        this DbContextOptionsBuilder<TContext> optionsBuilder,
+        DbConnection connection,
+        bool contextOwnsConnection,
+        Action<SqlServerDbContextOptionsBuilder>? sqlServerOptionsAction = null)
+        where TContext : DbContext
+        => (DbContextOptionsBuilder<TContext>)UseAzureSynapse(
+            (DbContextOptionsBuilder)optionsBuilder, connection, contextOwnsConnection, sqlServerOptionsAction);
+
+    /// <summary>
+    ///     Configures the context to connect to any of SQL Server, Azure SQL, Azure Synapse databases, but without initially setting any
+    ///     <see cref="DbConnection" /> or connection string.
+    /// </summary>
+    /// <remarks>
+    ///     <para>
+    ///         The connection or connection string must be set before the <see cref="DbContext" /> is used to connect
+    ///         to a database. Set a connection using <see cref="RelationalDatabaseFacadeExtensions.SetDbConnection" />.
+    ///         Set a connection string using <see cref="RelationalDatabaseFacadeExtensions.SetConnectionString" />.
+    ///     </para>
+    ///     <para>
+    ///         See <see href="https://aka.ms/efcore-docs-dbcontext-options">Using DbContextOptions</see>, and
+    ///         <see href="https://aka.ms/efcore-docs-sqlserver">Accessing SQL Server, Azure SQL, Azure Synapse databases with EF Core</see>
+    ///         for more information and examples.
+    ///     </para>
+    /// </remarks>
+    /// <param name="optionsBuilder">The builder being used to configure the context.</param>
+    /// <param name="sqlServerOptionsAction">An optional action to allow additional SQL Server, Azure SQL, Azure Synapse specific configuration.</param>
+    /// <returns>The options builder so that further configuration can be chained.</returns>
+    public static DbContextOptionsBuilder ConfigureSqlEngine(
+        this DbContextOptionsBuilder optionsBuilder,
+        Action<SqlServerDbContextOptionsBuilder>? sqlServerOptionsAction = null)
+    {
+        ((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(GetOrCreateExtension<SqlServerOptionsExtension>(optionsBuilder));
+        return ApplyConfiguration(optionsBuilder, sqlServerOptionsAction);
+    }
+
+    /// <summary>
+    ///     Configures the context to connect to any of SQL Server, Azure SQL, Azure Synapse databases, but without initially setting any
+    ///     <see cref="DbConnection" /> or connection string.
+    /// </summary>
+    /// <remarks>
+    ///     <para>
+    ///         The connection or connection string must be set before the <see cref="DbContext" /> is used to connect
+    ///         to a database. Set a connection using <see cref="RelationalDatabaseFacadeExtensions.SetDbConnection" />.
+    ///         Set a connection string using <see cref="RelationalDatabaseFacadeExtensions.SetConnectionString" />.
+    ///     </para>
+    ///     <para>
+    ///         See <see href="https://aka.ms/efcore-docs-dbcontext-options">Using DbContextOptions</see>, and
+    ///         <see href="https://aka.ms/efcore-docs-sqlserver">Accessing SQL Server, Azure SQL, Azure Synapse databases with EF Core</see>
+    ///         for more information and examples.
+    ///     </para>
+    /// </remarks>
+    /// <param name="optionsBuilder">The builder being used to configure the context.</param>
+    /// <param name="sqlServerOptionsAction">An optional action to allow additional SQL Server, Azure SQL, Azure Synapse specific configuration.</param>
+    /// <returns>The options builder so that further configuration can be chained.</returns>
+    public static DbContextOptionsBuilder<TContext> ConfigureSqlEngine<TContext>(
+        this DbContextOptionsBuilder<TContext> optionsBuilder,
+        Action<SqlServerDbContextOptionsBuilder>? sqlServerOptionsAction = null)
+        where TContext : DbContext
+        => (DbContextOptionsBuilder<TContext>)ConfigureSqlEngine(
+            (DbContextOptionsBuilder)optionsBuilder, sqlServerOptionsAction);
+
+    private static T GetOrCreateExtension<T>(DbContextOptionsBuilder optionsBuilder)
+        where T : RelationalOptionsExtension, new()
+        => optionsBuilder.Options.FindExtension<T>()
+            ?? new T();
 
     private static DbContextOptionsBuilder ApplyConfiguration(
         DbContextOptionsBuilder optionsBuilder,
@@ -245,7 +752,7 @@ private static DbContextOptionsBuilder ApplyConfiguration(
 
         sqlServerOptionsAction?.Invoke(new SqlServerDbContextOptionsBuilder(optionsBuilder));
 
-        var extension = (SqlServerOptionsExtension)GetOrCreateExtension(optionsBuilder).ApplyDefaults(optionsBuilder.Options);
+        var extension = GetOrCreateExtension<SqlServerOptionsExtension>(optionsBuilder).ApplyDefaults(optionsBuilder.Options);
         ((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);
 
         return optionsBuilder;
diff --git a/src/EFCore.SqlServer/Extensions/SqlServerServiceCollectionExtensions.cs b/src/EFCore.SqlServer/Extensions/SqlServerServiceCollectionExtensions.cs
index 12f2d4cf882..87f220451ed 100644
--- a/src/EFCore.SqlServer/Extensions/SqlServerServiceCollectionExtensions.cs
+++ b/src/EFCore.SqlServer/Extensions/SqlServerServiceCollectionExtensions.cs
@@ -15,7 +15,7 @@
 namespace Microsoft.Extensions.DependencyInjection;
 
 /// <summary>
-///     SQL Server specific extension methods for <see cref="IServiceCollection" />.
+///     SQL Server, Azure SQL, Azure Synapse specific extension methods for <see cref="IServiceCollection" />.
 /// </summary>
 public static class SqlServerServiceCollectionExtensions
 {
@@ -45,14 +45,14 @@ public static class SqlServerServiceCollectionExtensions
     ///     </para>
     ///     <para>
     ///         See <see href="https://aka.ms/efcore-docs-dbcontext-options">Using DbContextOptions</see>, and
-    ///         <see href="https://aka.ms/efcore-docs-sqlserver">Accessing SQL Server and Azure SQL databases with EF Core</see>
+    ///         <see href="https://aka.ms/efcore-docs-sqlserver">Accessing SQL Server, Azure SQL, Azure Synapse databases with EF Core</see>
     ///         for more information and examples.
     ///     </para>
     /// </remarks>
     /// <typeparam name="TContext">The type of context to be registered.</typeparam>
     /// <param name="serviceCollection">The <see cref="IServiceCollection" /> to add services to.</param>
     /// <param name="connectionString">The connection string of the database to connect to.</param>
-    /// <param name="sqlServerOptionsAction">An optional action to allow additional SQL Server specific configuration.</param>
+    /// <param name="sqlServerOptionsAction">An optional action to allow additional SQL Server, Azure SQL, Azure Synapse specific configuration.</param>
     /// <param name="optionsAction">An optional action to configure the <see cref="DbContextOptions" /> for the context.</param>
     /// <returns>The same service collection so that multiple calls can be chained.</returns>
     public static IServiceCollection AddSqlServer<TContext>(
@@ -91,6 +91,157 @@ public static IServiceCollection AddSqlServer<TContext>(
     /// </returns>
     [EditorBrowsable(EditorBrowsableState.Never)]
     public static IServiceCollection AddEntityFrameworkSqlServer(this IServiceCollection serviceCollection)
+        => AddEntityFrameworkSqlEngine(serviceCollection);
+
+    /// <summary>
+    ///     Registers the given Entity Framework <see cref="DbContext" /> as a service in the <see cref="IServiceCollection" />
+    ///     and configures it to connect to a Azure SQL database.
+    /// </summary>
+    /// <remarks>
+    ///     <para>
+    ///         This method is a shortcut for configuring a <see cref="DbContext" /> to use Azure SQL. It does not support all options.
+    ///         Use <see cref="O:EntityFrameworkServiceCollectionExtensions.AddDbContext" /> and related methods for full control of
+    ///         this process.
+    ///     </para>
+    ///     <para>
+    ///         Use this method when using dependency injection in your application, such as with ASP.NET Core.
+    ///         For applications that don't use dependency injection, consider creating <see cref="DbContext" />
+    ///         instances directly with its constructor. The <see cref="DbContext.OnConfiguring" /> method can then be
+    ///         overridden to configure the Azure SQL provider and connection string.
+    ///     </para>
+    ///     <para>
+    ///         To configure the <see cref="DbContextOptions{TContext}" /> for the context, either override the
+    ///         <see cref="DbContext.OnConfiguring" /> method in your derived context, or supply
+    ///         an optional action to configure the <see cref="DbContextOptions" /> for the context.
+    ///     </para>
+    ///     <para>
+    ///         See <see href="https://aka.ms/efcore-docs-di">Using DbContext with dependency injection</see> for more information and examples.
+    ///     </para>
+    ///     <para>
+    ///         See <see href="https://aka.ms/efcore-docs-dbcontext-options">Using DbContextOptions</see>, and
+    ///         <see href="https://aka.ms/efcore-docs-sqlserver">Accessing SQL Server, Azure SQL, Azure Synapse databases with EF Core</see>
+    ///         for more information and examples.
+    ///     </para>
+    /// </remarks>
+    /// <typeparam name="TContext">The type of context to be registered.</typeparam>
+    /// <param name="serviceCollection">The <see cref="IServiceCollection" /> to add services to.</param>
+    /// <param name="connectionString">The connection string of the database to connect to.</param>
+    /// <param name="sqlServerOptionsAction">An optional action to allow additional SQL Server, Azure SQL, Azure Synapse specific configuration.</param>
+    /// <param name="optionsAction">An optional action to configure the <see cref="DbContextOptions" /> for the context.</param>
+    /// <returns>The same service collection so that multiple calls can be chained.</returns>
+    public static IServiceCollection AddAzureSql<TContext>(
+        this IServiceCollection serviceCollection,
+        string? connectionString,
+        Action<SqlServerDbContextOptionsBuilder>? sqlServerOptionsAction = null,
+        Action<DbContextOptionsBuilder>? optionsAction = null)
+        where TContext : DbContext
+        => serviceCollection.AddDbContext<TContext>(
+            (_, options) =>
+            {
+                optionsAction?.Invoke(options);
+                options.UseAzureSql(connectionString, sqlServerOptionsAction);
+            });
+
+    /// <summary>
+    ///     <para>
+    ///         Adds the services required by the Microsoft Azure SQL database provider for Entity Framework
+    ///         to an <see cref="IServiceCollection" />.
+    ///     </para>
+    ///     <para>
+    ///         Warning: Do not call this method accidentally. It is much more likely you need
+    ///         to call <see cref="AddAzureSql{TContext}" />.
+    ///     </para>
+    /// </summary>
+    /// <remarks>
+    ///     Calling this method is no longer necessary when building most applications, including those that
+    ///     use dependency injection in ASP.NET or elsewhere.
+    ///     It is only needed when building the internal service provider for use with
+    ///     the <see cref="DbContextOptionsBuilder.UseInternalServiceProvider" /> method.
+    ///     This is not recommend other than for some advanced scenarios.
+    /// </remarks>
+    /// <param name="serviceCollection">The <see cref="IServiceCollection" /> to add services to.</param>
+    /// <returns>
+    ///     The same service collection so that multiple calls can be chained.
+    /// </returns>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public static IServiceCollection AddEntityFrameworkAzureSql(this IServiceCollection serviceCollection)
+        => AddEntityFrameworkSqlEngine(serviceCollection);
+
+    /// <summary>
+    ///     Registers the given Entity Framework <see cref="DbContext" /> as a service in the <see cref="IServiceCollection" />
+    ///     and configures it to connect to a Azure Synapse database.
+    /// </summary>
+    /// <remarks>
+    ///     <para>
+    ///         This method is a shortcut for configuring a <see cref="DbContext" /> to use Azure Synapse. It does not support all options.
+    ///         Use <see cref="O:EntityFrameworkServiceCollectionExtensions.AddDbContext" /> and related methods for full control of
+    ///         this process.
+    ///     </para>
+    ///     <para>
+    ///         Use this method when using dependency injection in your application, such as with ASP.NET Core.
+    ///         For applications that don't use dependency injection, consider creating <see cref="DbContext" />
+    ///         instances directly with its constructor. The <see cref="DbContext.OnConfiguring" /> method can then be
+    ///         overridden to configure the Azure Synapse provider and connection string.
+    ///     </para>
+    ///     <para>
+    ///         To configure the <see cref="DbContextOptions{TContext}" /> for the context, either override the
+    ///         <see cref="DbContext.OnConfiguring" /> method in your derived context, or supply
+    ///         an optional action to configure the <see cref="DbContextOptions" /> for the context.
+    ///     </para>
+    ///     <para>
+    ///         See <see href="https://aka.ms/efcore-docs-di">Using DbContext with dependency injection</see> for more information and examples.
+    ///     </para>
+    ///     <para>
+    ///         See <see href="https://aka.ms/efcore-docs-dbcontext-options">Using DbContextOptions</see>, and
+    ///         <see href="https://aka.ms/efcore-docs-sqlserver">Accessing SQL Server, Azure SQL, Azure Synapse databases with EF Core</see>
+    ///         for more information and examples.
+    ///     </para>
+    /// </remarks>
+    /// <typeparam name="TContext">The type of context to be registered.</typeparam>
+    /// <param name="serviceCollection">The <see cref="IServiceCollection" /> to add services to.</param>
+    /// <param name="connectionString">The connection string of the database to connect to.</param>
+    /// <param name="sqlServerOptionsAction">An optional action to allow additional SQL Server, Azure SQL, Azure Synapse specific configuration.</param>
+    /// <param name="optionsAction">An optional action to configure the <see cref="DbContextOptions" /> for the context.</param>
+    /// <returns>The same service collection so that multiple calls can be chained.</returns>
+    public static IServiceCollection AddAzureSynapse<TContext>(
+        this IServiceCollection serviceCollection,
+        string? connectionString,
+        Action<SqlServerDbContextOptionsBuilder>? sqlServerOptionsAction = null,
+        Action<DbContextOptionsBuilder>? optionsAction = null)
+        where TContext : DbContext
+        => serviceCollection.AddDbContext<TContext>(
+            (_, options) =>
+            {
+                optionsAction?.Invoke(options);
+                options.UseAzureSynapse(connectionString, sqlServerOptionsAction);
+            });
+
+    /// <summary>
+    ///     <para>
+    ///         Adds the services required by the Microsoft Azure Synapse database provider for Entity Framework
+    ///         to an <see cref="IServiceCollection" />.
+    ///     </para>
+    ///     <para>
+    ///         Warning: Do not call this method accidentally. It is much more likely you need
+    ///         to call <see cref="AddAzureSynapse{TContext}" />.
+    ///     </para>
+    /// </summary>
+    /// <remarks>
+    ///     Calling this method is no longer necessary when building most applications, including those that
+    ///     use dependency injection in ASP.NET or elsewhere.
+    ///     It is only needed when building the internal service provider for use with
+    ///     the <see cref="DbContextOptionsBuilder.UseInternalServiceProvider" /> method.
+    ///     This is not recommend other than for some advanced scenarios.
+    /// </remarks>
+    /// <param name="serviceCollection">The <see cref="IServiceCollection" /> to add services to.</param>
+    /// <returns>
+    ///     The same service collection so that multiple calls can be chained.
+    /// </returns>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public static IServiceCollection AddEntityFrameworkAzureSynapse(this IServiceCollection serviceCollection)
+        => AddEntityFrameworkSqlEngine(serviceCollection);
+
+    private static IServiceCollection AddEntityFrameworkSqlEngine(IServiceCollection serviceCollection)
     {
         new EntityFrameworkRelationalServicesBuilder(serviceCollection)
             .TryAdd<LoggingDefinitions, SqlServerLoggingDefinitions>()
diff --git a/src/EFCore.SqlServer/Infrastructure/Internal/ISqlServerSingletonOptions.cs b/src/EFCore.SqlServer/Infrastructure/Internal/ISqlServerSingletonOptions.cs
index f5f661d65d3..47728ddbc9d 100644
--- a/src/EFCore.SqlServer/Infrastructure/Internal/ISqlServerSingletonOptions.cs
+++ b/src/EFCore.SqlServer/Infrastructure/Internal/ISqlServerSingletonOptions.cs
@@ -17,7 +17,7 @@ public interface ISqlServerSingletonOptions : ISingletonOptions
     ///     any release. You should only use it directly in your code with extreme caution and knowing that
     ///     doing so can result in application failures when updating to a new Entity Framework Core release.
     /// </summary>
-    int CompatibilityLevel { get; }
+    public SqlServerEngineType EngineType { get; }
 
     /// <summary>
     ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -25,5 +25,21 @@ public interface ISqlServerSingletonOptions : ISingletonOptions
     ///     any release. You should only use it directly in your code with extreme caution and knowing that
     ///     doing so can result in application failures when updating to a new Entity Framework Core release.
     /// </summary>
-    int? CompatibilityLevelWithoutDefault { get; }
+    public int SqlServerCompatibilityLevel { get; }
+
+    /// <summary>
+    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
+    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
+    ///     any release. You should only use it directly in your code with extreme caution and knowing that
+    ///     doing so can result in application failures when updating to a new Entity Framework Core release.
+    /// </summary>
+    public int AzureSqlCompatibilityLevel { get; }
+
+    /// <summary>
+    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
+    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
+    ///     any release. You should only use it directly in your code with extreme caution and knowing that
+    ///     doing so can result in application failures when updating to a new Entity Framework Core release.
+    /// </summary>
+    public int AzureSynapseCompatibilityLevel { get; }
 }
diff --git a/src/EFCore.SqlServer/Infrastructure/Internal/SqlServerEngineType.cs b/src/EFCore.SqlServer/Infrastructure/Internal/SqlServerEngineType.cs
new file mode 100644
index 00000000000..63f9c9816f4
--- /dev/null
+++ b/src/EFCore.SqlServer/Infrastructure/Internal/SqlServerEngineType.cs
@@ -0,0 +1,33 @@
+﻿// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace Microsoft.EntityFrameworkCore.SqlServer.Infrastructure.Internal;
+
+/// <summary>
+///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
+///     the same compatibility standards as public APIs. It may be changed or removed without notice in
+///     any release. You should only use it directly in your code with extreme caution and knowing that
+///     doing so can result in application failures when updating to a new Entity Framework Core release.
+/// </summary>
+public enum SqlServerEngineType
+{
+    /// <summary>
+    /// Unknown SQL engine type.
+    /// </summary>
+    Unknown = 0,
+
+    /// <summary>
+    /// SQL Server.
+    /// </summary>
+    SqlServer = 1,
+
+    /// <summary>
+    /// Azure SQL.
+    /// </summary>
+    AzureSql = 2,
+
+    /// <summary>
+    /// Azure Synapse.
+    /// </summary>
+    AzureSynapse = 3,
+}
diff --git a/src/EFCore.SqlServer/Infrastructure/Internal/SqlServerOptionsExtension.cs b/src/EFCore.SqlServer/Infrastructure/Internal/SqlServerOptionsExtension.cs
index ccf3d1961b9..2fb912637a7 100644
--- a/src/EFCore.SqlServer/Infrastructure/Internal/SqlServerOptionsExtension.cs
+++ b/src/EFCore.SqlServer/Infrastructure/Internal/SqlServerOptionsExtension.cs
@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 
 using System.Text;
+using Microsoft.EntityFrameworkCore.SqlServer.Internal;
 
 namespace Microsoft.EntityFrameworkCore.SqlServer.Infrastructure.Internal;
 
@@ -14,8 +15,11 @@ namespace Microsoft.EntityFrameworkCore.SqlServer.Infrastructure.Internal;
 public class SqlServerOptionsExtension : RelationalOptionsExtension, IDbContextOptionsExtension
 {
     private DbContextOptionsExtensionInfo? _info;
-    private int? _compatibilityLevel;
-    private bool? _azureSql;
+    private SqlServerEngineType _engineType;
+    private bool _legacyAzureSql;
+    private int? _sqlServerCompatibilityLevel;
+    private int? _azureSqlCompatibilityLevel;
+    private int? _azureSynapseCompatibilityLevel;
 
     /// <summary>
     ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -29,7 +33,30 @@ public class SqlServerOptionsExtension : RelationalOptionsExtension, IDbContextO
     // SQL Server 2017 (14.x): compatibility level 140, start date 2017-09-29, mainstream end date 2022-10-11, extended end date 2027-10-12
     // SQL Server 2016 (13.x): compatibility level 130, start date 2016-06-01, mainstream end date 2021-07-13, extended end date 2026-07-14
     // SQL Server 2014 (12.x): compatibility level 120, start date 2014-06-05, mainstream end date 2019-07-09, extended end date 2024-07-09
-    public static readonly int DefaultCompatibilityLevel = 150;
+    public static readonly int SqlServerDefaultCompatibilityLevel = 150;
+
+    /// <summary>
+    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
+    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
+    ///     any release. You should only use it directly in your code with extreme caution and knowing that
+    ///     doing so can result in application failures when updating to a new Entity Framework Core release.
+    /// </summary>
+    // See https://learn.microsoft.com/sql/t-sql/statements/alter-database-transact-sql-compatibility-level
+    // SQL Server 2022 (16.x): compatibility level 160, start date 2022-11-16, mainstream end date 2028-01-11, extended end date 2033-01-11
+    // SQL Server 2019 (15.x): compatibility level 150, start date 2019-11-04, mainstream end date 2025-02-28, extended end date 2030-01-08
+    // SQL Server 2017 (14.x): compatibility level 140, start date 2017-09-29, mainstream end date 2022-10-11, extended end date 2027-10-12
+    // SQL Server 2016 (13.x): compatibility level 130, start date 2016-06-01, mainstream end date 2021-07-13, extended end date 2026-07-14
+    // SQL Server 2014 (12.x): compatibility level 120, start date 2014-06-05, mainstream end date 2019-07-09, extended end date 2024-07-09
+    public static readonly int AzureSqlDefaultCompatibilityLevel = 150;
+
+    /// <summary>
+    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
+    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
+    ///     any release. You should only use it directly in your code with extreme caution and knowing that
+    ///     doing so can result in application failures when updating to a new Entity Framework Core release.
+    /// </summary>
+    // See https://learn.microsoft.com/en-us/sql/t-sql/statements/alter-database-scoped-configuration-transact-sql
+    public static readonly int AzureSynapseDefaultCompatibilityLevel = 30;
 
     /// <summary>
     ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -52,8 +79,11 @@ public SqlServerOptionsExtension()
     protected SqlServerOptionsExtension(SqlServerOptionsExtension copyFrom)
         : base(copyFrom)
     {
-        _compatibilityLevel = copyFrom._compatibilityLevel;
-        _azureSql = copyFrom._azureSql;
+        _engineType = copyFrom._engineType;
+        _legacyAzureSql = copyFrom._legacyAzureSql;
+        _sqlServerCompatibilityLevel = copyFrom._sqlServerCompatibilityLevel;
+        _azureSqlCompatibilityLevel = copyFrom._azureSqlCompatibilityLevel;
+        _azureSynapseCompatibilityLevel = copyFrom._azureSynapseCompatibilityLevel;
     }
 
     /// <summary>
@@ -80,8 +110,64 @@ protected override RelationalOptionsExtension Clone()
     ///     any release. You should only use it directly in your code with extreme caution and knowing that
     ///     doing so can result in application failures when updating to a new Entity Framework Core release.
     /// </summary>
-    public virtual int CompatibilityLevel
-        => _compatibilityLevel ?? DefaultCompatibilityLevel;
+    public virtual SqlServerEngineType EngineType
+        => _engineType;
+
+    /// <summary>
+    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
+    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
+    ///     any release. You should only use it directly in your code with extreme caution and knowing that
+    ///     doing so can result in application failures when updating to a new Entity Framework Core release.
+    /// </summary>
+    public virtual bool LegacyAzureSql
+        => _legacyAzureSql;
+
+    /// <summary>
+    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
+    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
+    ///     any release. You should only use it directly in your code with extreme caution and knowing that
+    ///     doing so can result in application failures when updating to a new Entity Framework Core release.
+    /// </summary>
+    public virtual int SqlServerCompatibilityLevel
+        => _sqlServerCompatibilityLevel ?? SqlServerDefaultCompatibilityLevel;
+
+    /// <summary>
+    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
+    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
+    ///     any release. You should only use it directly in your code with extreme caution and knowing that
+    ///     doing so can result in application failures when updating to a new Entity Framework Core release.
+    /// </summary>
+    public virtual int AzureSqlCompatibilityLevel
+        => _azureSqlCompatibilityLevel ?? AzureSqlDefaultCompatibilityLevel;
+
+    /// <summary>
+    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
+    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
+    ///     any release. You should only use it directly in your code with extreme caution and knowing that
+    ///     doing so can result in application failures when updating to a new Entity Framework Core release.
+    /// </summary>
+    public virtual int AzureSynapseCompatibilityLevel
+        => _azureSynapseCompatibilityLevel ?? AzureSynapseDefaultCompatibilityLevel;
+
+    /// <summary>
+    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
+    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
+    ///     any release. You should only use it directly in your code with extreme caution and knowing that
+    ///     doing so can result in application failures when updating to a new Entity Framework Core release.
+    /// </summary>
+    public virtual SqlServerOptionsExtension WithEngineType(SqlServerEngineType engineType)
+    {
+        if (EngineType != SqlServerEngineType.Unknown && EngineType != engineType)
+        {
+            throw new InvalidOperationException(SqlServerStrings.AlreadyConfiguredEngineType(engineType, EngineType));
+        }
+
+        var clone = (SqlServerOptionsExtension)Clone();
+
+        clone._engineType = engineType;
+
+        return clone;
+    }
 
     /// <summary>
     ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -89,8 +175,15 @@ public virtual int CompatibilityLevel
     ///     any release. You should only use it directly in your code with extreme caution and knowing that
     ///     doing so can result in application failures when updating to a new Entity Framework Core release.
     /// </summary>
-    public virtual int? CompatibilityLevelWithoutDefault
-        => _compatibilityLevel;
+    public virtual SqlServerOptionsExtension WithLegacyAzureSql(bool enable)
+    {
+        var clone = (SqlServerOptionsExtension)Clone();
+
+        clone._engineType = SqlServerEngineType.SqlServer;
+        clone._legacyAzureSql = enable;
+
+        return clone;
+    }
 
     /// <summary>
     ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -98,11 +191,11 @@ public virtual int? CompatibilityLevelWithoutDefault
     ///     any release. You should only use it directly in your code with extreme caution and knowing that
     ///     doing so can result in application failures when updating to a new Entity Framework Core release.
     /// </summary>
-    public virtual SqlServerOptionsExtension WithCompatibilityLevel(int? compatibilityLevel)
+    public virtual SqlServerOptionsExtension WithSqlServerCompatibilityLevel(int? sqlServerCompatibilityLevel)
     {
         var clone = (SqlServerOptionsExtension)Clone();
 
-        clone._compatibilityLevel = compatibilityLevel;
+        clone._sqlServerCompatibilityLevel = sqlServerCompatibilityLevel;
 
         return clone;
     }
@@ -113,8 +206,14 @@ public virtual SqlServerOptionsExtension WithCompatibilityLevel(int? compatibili
     ///     any release. You should only use it directly in your code with extreme caution and knowing that
     ///     doing so can result in application failures when updating to a new Entity Framework Core release.
     /// </summary>
-    public virtual bool IsAzureSql
-        => _azureSql ?? false;
+    public virtual SqlServerOptionsExtension WithAzureSqlCompatibilityLevel(int? azureSqlCompatibilityLevel)
+    {
+        var clone = (SqlServerOptionsExtension)Clone();
+
+        clone._azureSqlCompatibilityLevel = azureSqlCompatibilityLevel;
+
+        return clone;
+    }
 
     /// <summary>
     ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -122,11 +221,11 @@ public virtual bool IsAzureSql
     ///     any release. You should only use it directly in your code with extreme caution and knowing that
     ///     doing so can result in application failures when updating to a new Entity Framework Core release.
     /// </summary>
-    public virtual SqlServerOptionsExtension WithAzureSql(bool enable)
+    public virtual SqlServerOptionsExtension WithAzureSynapseCompatibilityLevel(int? azureSynapseCompatibilityLevel)
     {
         var clone = (SqlServerOptionsExtension)Clone();
 
-        clone._azureSql = enable;
+        clone._azureSynapseCompatibilityLevel = _azureSynapseCompatibilityLevel;
 
         return clone;
     }
@@ -134,12 +233,8 @@ public virtual SqlServerOptionsExtension WithAzureSql(bool enable)
     /// <inheritdoc />
     public virtual IDbContextOptionsExtension ApplyDefaults(IDbContextOptions options)
     {
-        if (!IsAzureSql)
-        {
-            return this;
-        }
-
-        if (ExecutionStrategyFactory == null)
+        if (ExecutionStrategyFactory == null
+            && (EngineType == SqlServerEngineType.AzureSql || EngineType == SqlServerEngineType.AzureSynapse || LegacyAzureSql))
         {
             return WithExecutionStrategyFactory(c => new SqlServerRetryingExecutionStrategy(c));
         }
@@ -154,7 +249,35 @@ public virtual IDbContextOptionsExtension ApplyDefaults(IDbContextOptions option
     ///     doing so can result in application failures when updating to a new Entity Framework Core release.
     /// </summary>
     public override void ApplyServices(IServiceCollection services)
-        => services.AddEntityFrameworkSqlServer();
+    {
+        switch (_engineType)
+        {
+            case SqlServerEngineType.SqlServer:
+                services.AddEntityFrameworkSqlServer();
+                break;
+            case SqlServerEngineType.AzureSql:
+                services.AddEntityFrameworkAzureSql();
+                break;
+            case SqlServerEngineType.AzureSynapse:
+                services.AddEntityFrameworkAzureSynapse();
+                break;
+        }
+    }
+
+    /// <summary>
+    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
+    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
+    ///     any release. You should only use it directly in your code with extreme caution and knowing that
+    ///     doing so can result in application failures when updating to a new Entity Framework Core release.
+    /// </summary>
+    public override void Validate(IDbContextOptions options)
+    {
+        base.Validate(options);
+        if (EngineType == SqlServerEngineType.Unknown)
+        {
+            throw new InvalidOperationException(SqlServerStrings.InvalidEngineType($"{nameof(SqlServerDbContextOptionsExtensions.UseSqlServer)}/{nameof(SqlServerDbContextOptionsExtensions.UseAzureSql)}/{nameof(SqlServerDbContextOptionsExtensions.UseAzureSynapse)}"));
+        }
+    }
 
     private sealed class ExtensionInfo : RelationalExtensionInfo
     {
@@ -168,12 +291,12 @@ public ExtensionInfo(IDbContextOptionsExtension extension)
         private new SqlServerOptionsExtension Extension
             => (SqlServerOptionsExtension)base.Extension;
 
-        public override bool IsDatabaseProvider
-            => true;
-
         public override bool ShouldUseSameServiceProvider(DbContextOptionsExtensionInfo other)
             => other is ExtensionInfo otherInfo
-                && Extension.CompatibilityLevel == otherInfo.Extension.CompatibilityLevel;
+                && Extension.EngineType == otherInfo.Extension.EngineType
+                && Extension.SqlServerCompatibilityLevel == otherInfo.Extension.SqlServerCompatibilityLevel
+                && Extension.AzureSqlCompatibilityLevel == otherInfo.Extension.AzureSqlCompatibilityLevel
+                && Extension.AzureSynapseCompatibilityLevel == otherInfo.Extension.AzureSynapseCompatibilityLevel;
 
         public override string LogFragment
         {
@@ -185,11 +308,39 @@ public override string LogFragment
 
                     builder.Append(base.LogFragment);
 
-                    if (Extension._compatibilityLevel is int compatibilityLevel)
+                    builder
+                        .Append("EngineType=")
+                        .Append(Extension._engineType)
+                        .Append(' ');
+
+                    if (Extension._legacyAzureSql)
                     {
                         builder
-                            .Append("CompatibilityLevel=")
-                            .Append(compatibilityLevel);
+                            .Append("LegacyAzureSql=")
+                            .Append(Extension._legacyAzureSql)
+                            .Append(' ');
+                    }
+
+                    if (Extension._sqlServerCompatibilityLevel != null)
+                    {
+                        builder
+                            .Append("SqlServerCompatibilityLevel=")
+                            .Append(Extension._sqlServerCompatibilityLevel)
+                            .Append(' ');
+                    }
+                    if (Extension._azureSqlCompatibilityLevel != null)
+                    {
+                        builder
+                            .Append("AzureSqlCompatibilityLevel=")
+                            .Append(Extension._azureSqlCompatibilityLevel)
+                            .Append(' ');
+                    }
+                    if (Extension._azureSynapseCompatibilityLevel != null)
+                    {
+                        builder
+                            .Append("AzureSynapseCompatibilityLevel=")
+                            .Append(Extension._azureSynapseCompatibilityLevel)
+                            .Append(' ');
                     }
 
                     _logFragment = builder.ToString();
@@ -201,11 +352,20 @@ public override string LogFragment
 
         public override void PopulateDebugInfo(IDictionary<string, string> debugInfo)
         {
-            debugInfo["SqlServer"] = "1";
+            debugInfo["EngineType"] = Extension.EngineType.ToString();
+            debugInfo["LegacyAzureSql"] = Extension.LegacyAzureSql.ToString();
 
-            if (Extension.CompatibilityLevel is int compatibilityLevel)
+            if (Extension.SqlServerCompatibilityLevel is int sqlServerCompatibilityLevel)
+            {
+                debugInfo["SqlServerCompatibilityLevel"] = sqlServerCompatibilityLevel.ToString();
+            }
+            if (Extension.AzureSqlCompatibilityLevel is int azureSqlCompatibilityLevel)
+            {
+                debugInfo["AzureSqlCompatibilityLevel"] = azureSqlCompatibilityLevel.ToString();
+            }
+            if (Extension.AzureSynapseCompatibilityLevel is int azureSynapseCompatibilityLevel)
             {
-                debugInfo["CompatibilityLevel"] = compatibilityLevel.ToString();
+                debugInfo["AzureSynapseCompatibilityLevel"] = azureSynapseCompatibilityLevel.ToString();
             }
         }
     }
diff --git a/src/EFCore.SqlServer/Infrastructure/Internal/SqlServerSingletonOptions.cs b/src/EFCore.SqlServer/Infrastructure/Internal/SqlServerSingletonOptions.cs
index cba62d8cd69..3af5096042c 100644
--- a/src/EFCore.SqlServer/Infrastructure/Internal/SqlServerSingletonOptions.cs
+++ b/src/EFCore.SqlServer/Infrastructure/Internal/SqlServerSingletonOptions.cs
@@ -17,7 +17,7 @@ public class SqlServerSingletonOptions : ISqlServerSingletonOptions
     ///     any release. You should only use it directly in your code with extreme caution and knowing that
     ///     doing so can result in application failures when updating to a new Entity Framework Core release.
     /// </summary>
-    public virtual int CompatibilityLevel { get; private set; } = SqlServerOptionsExtension.DefaultCompatibilityLevel;
+    public virtual SqlServerEngineType EngineType { get; private set; }
 
     /// <summary>
     ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -25,7 +25,23 @@ public class SqlServerSingletonOptions : ISqlServerSingletonOptions
     ///     any release. You should only use it directly in your code with extreme caution and knowing that
     ///     doing so can result in application failures when updating to a new Entity Framework Core release.
     /// </summary>
-    public virtual int? CompatibilityLevelWithoutDefault { get; private set; }
+    public virtual int SqlServerCompatibilityLevel { get; private set; } = SqlServerOptionsExtension.SqlServerDefaultCompatibilityLevel;
+
+    /// <summary>
+    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
+    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
+    ///     any release. You should only use it directly in your code with extreme caution and knowing that
+    ///     doing so can result in application failures when updating to a new Entity Framework Core release.
+    /// </summary>
+    public virtual int AzureSqlCompatibilityLevel { get; private set; } = SqlServerOptionsExtension.AzureSqlDefaultCompatibilityLevel;
+
+    /// <summary>
+    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
+    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
+    ///     any release. You should only use it directly in your code with extreme caution and knowing that
+    ///     doing so can result in application failures when updating to a new Entity Framework Core release.
+    /// </summary>
+    public virtual int AzureSynapseCompatibilityLevel { get; private set; } = SqlServerOptionsExtension.AzureSynapseDefaultCompatibilityLevel;
 
     /// <summary>
     ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -38,8 +54,10 @@ public virtual void Initialize(IDbContextOptions options)
         var sqlServerOptions = options.FindExtension<SqlServerOptionsExtension>();
         if (sqlServerOptions != null)
         {
-            CompatibilityLevel = sqlServerOptions.CompatibilityLevel;
-            CompatibilityLevelWithoutDefault = sqlServerOptions.CompatibilityLevelWithoutDefault;
+            EngineType = sqlServerOptions.EngineType;
+            SqlServerCompatibilityLevel = sqlServerOptions.SqlServerCompatibilityLevel;
+            AzureSqlCompatibilityLevel = sqlServerOptions.AzureSqlCompatibilityLevel;
+            AzureSynapseCompatibilityLevel = sqlServerOptions.AzureSynapseCompatibilityLevel;
         }
     }
 
@@ -51,16 +69,34 @@ public virtual void Initialize(IDbContextOptions options)
     /// </summary>
     public virtual void Validate(IDbContextOptions options)
     {
-        var sqlserverOptions = options.FindExtension<SqlServerOptionsExtension>();
+        var sqlServerOptions = options.FindExtension<SqlServerOptionsExtension>();
 
-        if (sqlserverOptions != null
-            && (CompatibilityLevelWithoutDefault != sqlserverOptions.CompatibilityLevelWithoutDefault
-                || CompatibilityLevel != sqlserverOptions.CompatibilityLevel))
+        if (sqlServerOptions != null)
         {
-            throw new InvalidOperationException(
-                CoreStrings.SingletonOptionChanged(
-                    nameof(SqlServerDbContextOptionsExtensions.UseSqlServer),
-                    nameof(DbContextOptionsBuilder.UseInternalServiceProvider)));
+            if (EngineType == SqlServerEngineType.SqlServer
+                && (EngineType != sqlServerOptions.EngineType || SqlServerCompatibilityLevel != sqlServerOptions.SqlServerCompatibilityLevel))
+            {
+                throw new InvalidOperationException(
+                    CoreStrings.SingletonOptionChanged(
+                        $"{nameof(SqlServerDbContextOptionsExtensions.UseSqlServer)}",
+                        nameof(DbContextOptionsBuilder.UseInternalServiceProvider)));
+            }
+            if (EngineType == SqlServerEngineType.AzureSql
+                && (EngineType != sqlServerOptions.EngineType || AzureSqlCompatibilityLevel != sqlServerOptions.AzureSqlCompatibilityLevel))
+            {
+                throw new InvalidOperationException(
+                    CoreStrings.SingletonOptionChanged(
+                        $"{nameof(SqlServerDbContextOptionsExtensions.UseAzureSql)}",
+                        nameof(DbContextOptionsBuilder.UseInternalServiceProvider)));
+            }
+            if (EngineType == SqlServerEngineType.AzureSynapse
+                && (EngineType != sqlServerOptions.EngineType || AzureSynapseCompatibilityLevel != sqlServerOptions.AzureSynapseCompatibilityLevel))
+            {
+                throw new InvalidOperationException(
+                    CoreStrings.SingletonOptionChanged(
+                        $"{nameof(SqlServerDbContextOptionsExtensions.UseAzureSynapse)}",
+                        nameof(DbContextOptionsBuilder.UseInternalServiceProvider)));
+            }
         }
     }
 }
diff --git a/src/EFCore.SqlServer/Infrastructure/SqlServerDbContextOptionsBuilder.cs b/src/EFCore.SqlServer/Infrastructure/SqlServerDbContextOptionsBuilder.cs
index c3f74d0bd91..863dcac7192 100644
--- a/src/EFCore.SqlServer/Infrastructure/SqlServerDbContextOptionsBuilder.cs
+++ b/src/EFCore.SqlServer/Infrastructure/SqlServerDbContextOptionsBuilder.cs
@@ -6,10 +6,13 @@
 namespace Microsoft.EntityFrameworkCore.Infrastructure;
 
 /// <summary>
-///     Allows SQL Server specific configuration to be performed on <see cref="DbContextOptions" />.
+///     Allows SQL Server, Azure SQL, Azure Synapse specific configuration to be performed on <see cref="DbContextOptions" />.
 /// </summary>
 /// <remarks>
-///     Instances of this class are returned from a call to <see cref="O:SqlServerDbContextOptionsExtensions.UseSqlServer" />
+///     Instances of this class are returned from a call to 
+///     <see cref="O:SqlServerDbContextOptionsExtensions.UseSqlServer" />, 
+///     <see cref="O:SqlServerDbContextOptionsExtensions.UseAzureSql" />, 
+///     <see cref="O:SqlServerDbContextOptionsExtensions.UseAzureSynapse" /> 
 ///     and it is not designed to be directly constructed in your application code.
 /// </remarks>
 public class SqlServerDbContextOptionsBuilder
@@ -29,7 +32,7 @@ public SqlServerDbContextOptionsBuilder(DbContextOptionsBuilder optionsBuilder)
     /// </summary>
     /// <remarks>
     ///     <para>
-    ///         This strategy is specifically tailored to SQL Server (including Azure SQL). It is pre-configured with
+    ///         This strategy is specifically tailored to SQL Server, Azure SQL, Azure Synapse. It is pre-configured with
     ///         error numbers for transient errors that can be retried.
     ///     </para>
     ///     <para>
@@ -48,7 +51,7 @@ public virtual SqlServerDbContextOptionsBuilder EnableRetryOnFailure()
     /// </summary>
     /// <remarks>
     ///     <para>
-    ///         This strategy is specifically tailored to SQL Server (including Azure SQL). It is pre-configured with
+    ///         This strategy is specifically tailored to SQL Server, Azure SQL, Azure Synapse. It is pre-configured with
     ///         error numbers for transient errors that can be retried.
     ///     </para>
     ///     <para>
@@ -67,7 +70,7 @@ public virtual SqlServerDbContextOptionsBuilder EnableRetryOnFailure(int maxRetr
     /// </summary>
     /// <remarks>
     ///     <para>
-    ///         This strategy is specifically tailored to SQL Server (including Azure SQL). It is pre-configured with
+    ///         This strategy is specifically tailored to SQL Server, Azure SQL, Azure Synapse. It is pre-configured with
     ///         error numbers for transient errors that can be retried.
     ///     </para>
     ///     <para>
@@ -87,7 +90,7 @@ public virtual SqlServerDbContextOptionsBuilder EnableRetryOnFailure(ICollection
     /// </summary>
     /// <remarks>
     ///     <para>
-    ///         This strategy is specifically tailored to SQL Server (including Azure SQL). It is pre-configured with
+    ///         This strategy is specifically tailored to SQL Server, Azure SQL, Azure Synapse. It is pre-configured with
     ///         error numbers for transient errors that can be retried, but additional error numbers can also be supplied.
     ///     </para>
     ///     <para>
@@ -116,14 +119,45 @@ public virtual SqlServerDbContextOptionsBuilder EnableRetryOnFailure(
     ///     </see>
     ///     for more information and examples.
     /// </remarks>
-    /// <param name="compatibilityLevel"><see langword="false" /> to have null resource</param>
-    public virtual SqlServerDbContextOptionsBuilder UseCompatibilityLevel(int compatibilityLevel)
-        => WithOption(e => e.WithCompatibilityLevel(compatibilityLevel));
+    /// <param name="sqlServerCompatibilityLevel"><see langword="false" /> to have null resource</param>
+    public virtual SqlServerDbContextOptionsBuilder UseSqlServerCompatibilityLevel(int sqlServerCompatibilityLevel)
+        => WithOption(e => e.WithSqlServerCompatibilityLevel(sqlServerCompatibilityLevel));
 
     /// <summary>
     ///     Configures the context to use defaults optimized for Azure SQL, including retries on errors.
     /// </summary>
     /// <param name="enable">Whether the defaults should be enabled.</param>
+    [Obsolete("Use UseAzureSql instead of UseSqlServer with UseAzureSqlDefaults.")]
     public virtual SqlServerDbContextOptionsBuilder UseAzureSqlDefaults(bool enable = true)
-        => WithOption(e => e.WithAzureSql(enable));
+        => WithOption(e => e.WithLegacyAzureSql(enable));
+
+    /// <summary>
+    ///     Sets the Azure SQL compatibility level that EF Core will use when interacting with the database. This allows configuring EF
+    ///     Core to work with older (or newer) versions of Azure SQL. Defaults to <c>160</c>.
+    /// </summary>
+    /// <remarks>
+    ///     See <see href="https://aka.ms/efcore-docs-dbcontext-options">Using DbContextOptions</see>, and
+    ///     <see href="https://learn.microsoft.com/en-us/sql/t-sql/statements/alter-database-scoped-configuration-transact-sql">
+    ///         Azure SQL documentation on compatibility level
+    ///     </see>
+    ///     for more information and examples.
+    /// </remarks>
+    /// <param name="azureSqlCompatibilityLevel"><see langword="false" /> to have null resource</param>
+    public virtual SqlServerDbContextOptionsBuilder UseAzureSqlCompatibilityLevel(int azureSqlCompatibilityLevel)
+        => WithOption(e => e.WithAzureSqlCompatibilityLevel(azureSqlCompatibilityLevel));
+
+    /// <summary>
+    ///     Sets the Azure Synapse compatibility level that EF Core will use when interacting with the database. This allows configuring EF
+    ///     Core to work with older (or newer) versions of Azure Synapse. Defaults to <c>30</c>.
+    /// </summary>
+    /// <remarks>
+    ///     See <see href="https://aka.ms/efcore-docs-dbcontext-options">Using DbContextOptions</see>, and
+    ///     <see href="https://learn.microsoft.com/en-us/sql/t-sql/statements/alter-database-scoped-configuration-transact-sql">
+    ///         Azure Synapse documentation on compatibility level
+    ///     </see>
+    ///     for more information and examples.
+    /// </remarks>
+    /// <param name="azureSynapseCompatibilityLevel"><see langword="false" /> to have null resource</param>
+    public virtual SqlServerDbContextOptionsBuilder UseAzureSynapseCompatibilityLevel(int azureSynapseCompatibilityLevel)
+        => WithOption(e => e.WithAzureSynapseCompatibilityLevel(azureSynapseCompatibilityLevel));
 }
diff --git a/src/EFCore.SqlServer/Properties/SqlServerStrings.Designer.cs b/src/EFCore.SqlServer/Properties/SqlServerStrings.Designer.cs
index 44bf55728a3..a2394614e7c 100644
--- a/src/EFCore.SqlServer/Properties/SqlServerStrings.Designer.cs
+++ b/src/EFCore.SqlServer/Properties/SqlServerStrings.Designer.cs
@@ -23,6 +23,14 @@ public static class SqlServerStrings
         private static readonly ResourceManager _resourceManager
             = new ResourceManager("Microsoft.EntityFrameworkCore.SqlServer.Properties.SqlServerStrings", typeof(SqlServerStrings).Assembly);
 
+        /// <summary>
+        ///     Cannot configure engine type '{newEngineType}', because engine type was already configured as '{oldEngineType}'.
+        /// </summary>
+        public static string AlreadyConfiguredEngineType(object? newEngineType, object? oldEngineType)
+            => string.Format(
+                GetString("AlreadyConfiguredEngineType", nameof(newEngineType), nameof(oldEngineType)),
+                newEngineType, oldEngineType);
+
         /// <summary>
         ///     To change the IDENTITY property of a column, the column needs to be dropped and recreated.
         /// </summary>
@@ -207,6 +215,14 @@ public static string IndexTableRequired
         public static string InvalidColumnNameForFreeText
             => GetString("InvalidColumnNameForFreeText");
 
+        /// <summary>
+        ///     Engine type was not configured. Use one of {methods} to configure it.
+        /// </summary>
+        public static string InvalidEngineType(object? methods)
+            => string.Format(
+                GetString("InvalidEngineType", nameof(methods)),
+                methods);
+
         /// <summary>
         ///     The specified table '{table}' is not in a valid format. Specify tables using the format '[schema].[table]'.
         /// </summary>
diff --git a/src/EFCore.SqlServer/Properties/SqlServerStrings.resx b/src/EFCore.SqlServer/Properties/SqlServerStrings.resx
index ba817be851a..5b734aebd29 100644
--- a/src/EFCore.SqlServer/Properties/SqlServerStrings.resx
+++ b/src/EFCore.SqlServer/Properties/SqlServerStrings.resx
@@ -117,6 +117,9 @@
   <resheader name="writer">
     <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </resheader>
+  <data name="AlreadyConfiguredEngineType" xml:space="preserve">
+    <value>Cannot configure engine type '{newEngineType}', because engine type was already configured as '{oldEngineType}'.</value>
+  </data>
   <data name="AlterIdentityColumn" xml:space="preserve">
     <value>To change the IDENTITY property of a column, the column needs to be dropped and recreated.</value>
   </data>
@@ -189,6 +192,9 @@
   <data name="InvalidColumnNameForFreeText" xml:space="preserve">
     <value>The expression passed to the 'propertyReference' parameter of the 'FreeText' method is not a valid reference to a property. The expression must represent a reference to a full-text indexed property on the object referenced in the from clause: 'from e in context.Entities where EF.Functions.FreeText(e.SomeProperty, textToSearchFor) select e'</value>
   </data>
+  <data name="InvalidEngineType" xml:space="preserve">
+    <value>Engine type was not configured. Use one of {methods} to configure it.</value>
+  </data>
   <data name="InvalidTableToIncludeInScaffolding" xml:space="preserve">
     <value>The specified table '{table}' is not in a valid format. Specify tables using the format '[schema].[table]'.</value>
   </data>
diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerQuerySqlGenerator.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerQuerySqlGenerator.cs
index 994ee50a4f8..67c7726df4a 100644
--- a/src/EFCore.SqlServer/Query/Internal/SqlServerQuerySqlGenerator.cs
+++ b/src/EFCore.SqlServer/Query/Internal/SqlServerQuerySqlGenerator.cs
@@ -19,7 +19,7 @@ public class SqlServerQuerySqlGenerator : QuerySqlGenerator
 {
     private readonly IRelationalTypeMappingSource _typeMappingSource;
     private readonly ISqlGenerationHelper _sqlGenerationHelper;
-    private readonly int _sqlServerCompatibilityLevel;
+    private readonly ISqlServerSingletonOptions _sqlServerSingletonOptions;
 
     private bool _withinTable;
 
@@ -37,7 +37,7 @@ public SqlServerQuerySqlGenerator(
     {
         _typeMappingSource = typeMappingSource;
         _sqlGenerationHelper = dependencies.SqlGenerationHelper;
-        _sqlServerCompatibilityLevel = sqlServerSingletonOptions.CompatibilityLevel;
+        _sqlServerSingletonOptions = sqlServerSingletonOptions;
     }
 
     /// <summary>
@@ -520,18 +520,26 @@ private void GenerateJsonPath(IReadOnlyList<PathSegment> path)
                     {
                         Visit(arrayIndex);
                     }
-                    else if (_sqlServerCompatibilityLevel >= 140)
-                    {
-                        Sql.Append("' + CAST(");
-                        Visit(arrayIndex);
-                        Sql.Append(" AS ");
-                        Sql.Append(_typeMappingSource.GetMapping(typeof(string)).StoreType);
-                        Sql.Append(") + '");
-                    }
                     else
                     {
-                        throw new InvalidOperationException(
-                            SqlServerStrings.JsonValuePathExpressionsNotSupported(_sqlServerCompatibilityLevel));
+                        switch (_sqlServerSingletonOptions.EngineType)
+                        {
+                            case SqlServerEngineType.SqlServer when _sqlServerSingletonOptions.SqlServerCompatibilityLevel >= 140:
+                            case SqlServerEngineType.AzureSql when _sqlServerSingletonOptions.AzureSqlCompatibilityLevel >= 140:
+                            case SqlServerEngineType.AzureSynapse:
+                                Sql.Append("' + CAST(");
+                                Visit(arrayIndex);
+                                Sql.Append(" AS ");
+                                Sql.Append(_typeMappingSource.GetMapping(typeof(string)).StoreType);
+                                Sql.Append(") + '");
+                                break;
+                            case SqlServerEngineType.SqlServer:
+                                throw new InvalidOperationException(
+                                    SqlServerStrings.JsonValuePathExpressionsNotSupported(_sqlServerSingletonOptions.SqlServerCompatibilityLevel));
+                            case SqlServerEngineType.AzureSql:
+                                throw new InvalidOperationException(
+                                    SqlServerStrings.JsonValuePathExpressionsNotSupported(_sqlServerSingletonOptions.AzureSqlCompatibilityLevel));
+                        }
                     }
 
                     Sql.Append("]");
diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerQueryableMethodTranslatingExpressionVisitor.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerQueryableMethodTranslatingExpressionVisitor.cs
index 9ce6e9d5425..c48965fc33f 100644
--- a/src/EFCore.SqlServer/Query/Internal/SqlServerQueryableMethodTranslatingExpressionVisitor.cs
+++ b/src/EFCore.SqlServer/Query/Internal/SqlServerQueryableMethodTranslatingExpressionVisitor.cs
@@ -20,7 +20,7 @@ public class SqlServerQueryableMethodTranslatingExpressionVisitor : RelationalQu
     private readonly SqlServerQueryCompilationContext _queryCompilationContext;
     private readonly IRelationalTypeMappingSource _typeMappingSource;
     private readonly ISqlExpressionFactory _sqlExpressionFactory;
-    private readonly int _sqlServerCompatibilityLevel;
+    private readonly ISqlServerSingletonOptions _sqlServerSingletonOptions;
 
     private RelationalTypeMapping? _nvarcharMaxTypeMapping;
 
@@ -40,8 +40,7 @@ public SqlServerQueryableMethodTranslatingExpressionVisitor(
         _queryCompilationContext = queryCompilationContext;
         _typeMappingSource = relationalDependencies.TypeMappingSource;
         _sqlExpressionFactory = relationalDependencies.SqlExpressionFactory;
-
-        _sqlServerCompatibilityLevel = sqlServerSingletonOptions.CompatibilityLevel;
+        _sqlServerSingletonOptions = sqlServerSingletonOptions;
     }
 
     /// <summary>
@@ -57,8 +56,7 @@ protected SqlServerQueryableMethodTranslatingExpressionVisitor(
         _queryCompilationContext = parentVisitor._queryCompilationContext;
         _typeMappingSource = parentVisitor._typeMappingSource;
         _sqlExpressionFactory = parentVisitor._sqlExpressionFactory;
-
-        _sqlServerCompatibilityLevel = parentVisitor._sqlServerCompatibilityLevel;
+        _sqlServerSingletonOptions = parentVisitor._sqlServerSingletonOptions;
     }
 
     /// <summary>
@@ -131,9 +129,15 @@ protected override Expression VisitExtension(Expression extensionExpression)
         IProperty? property,
         string tableAlias)
     {
-        if (_sqlServerCompatibilityLevel < 130)
+        if (_sqlServerSingletonOptions.EngineType == SqlServerEngineType.SqlServer && _sqlServerSingletonOptions.SqlServerCompatibilityLevel < 130)
+        {
+            AddTranslationErrorDetails(SqlServerStrings.CompatibilityLevelTooLowForScalarCollections(_sqlServerSingletonOptions.SqlServerCompatibilityLevel));
+
+            return null;
+        }
+        if (_sqlServerSingletonOptions.EngineType == SqlServerEngineType.AzureSql && _sqlServerSingletonOptions.AzureSqlCompatibilityLevel < 130)
         {
-            AddTranslationErrorDetails(SqlServerStrings.CompatibilityLevelTooLowForScalarCollections(_sqlServerCompatibilityLevel));
+            AddTranslationErrorDetails(SqlServerStrings.CompatibilityLevelTooLowForScalarCollections(_sqlServerSingletonOptions.AzureSqlCompatibilityLevel));
 
             return null;
         }
diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerSqlExpressionFactory.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerSqlExpressionFactory.cs
index df768474719..f84f3e1abb8 100644
--- a/src/EFCore.SqlServer/Query/Internal/SqlServerSqlExpressionFactory.cs
+++ b/src/EFCore.SqlServer/Query/Internal/SqlServerSqlExpressionFactory.cs
@@ -16,7 +16,6 @@ namespace Microsoft.EntityFrameworkCore.SqlServer.Query.Internal;
 public class SqlServerSqlExpressionFactory : SqlExpressionFactory
 {
     private readonly IRelationalTypeMappingSource _typeMappingSource;
-    private readonly int _sqlServerCompatibilityLevel;
 
     /// <summary>
     ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -25,12 +24,10 @@ public class SqlServerSqlExpressionFactory : SqlExpressionFactory
     ///     doing so can result in application failures when updating to a new Entity Framework Core release.
     /// </summary>
     public SqlServerSqlExpressionFactory(
-        SqlExpressionFactoryDependencies dependencies,
-        ISqlServerSingletonOptions sqlServerSingletonOptions)
+        SqlExpressionFactoryDependencies dependencies)
         : base(dependencies)
     {
         _typeMappingSource = dependencies.TypeMappingSource;
-        _sqlServerCompatibilityLevel = sqlServerSingletonOptions.CompatibilityLevel;
     }
 
     /// <summary>
diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerSqlTranslatingExpressionVisitor.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerSqlTranslatingExpressionVisitor.cs
index 677fe36f4ed..402b615a13e 100644
--- a/src/EFCore.SqlServer/Query/Internal/SqlServerSqlTranslatingExpressionVisitor.cs
+++ b/src/EFCore.SqlServer/Query/Internal/SqlServerSqlTranslatingExpressionVisitor.cs
@@ -21,7 +21,7 @@ public class SqlServerSqlTranslatingExpressionVisitor : RelationalSqlTranslating
     private readonly SqlServerQueryCompilationContext _queryCompilationContext;
     private readonly ISqlExpressionFactory _sqlExpressionFactory;
     private readonly IRelationalTypeMappingSource _typeMappingSource;
-    private readonly int _sqlServerCompatibilityLevel;
+    private readonly ISqlServerSingletonOptions _sqlServerSingletonOptions;
 
     private static readonly HashSet<string> DateTimeDataTypes
         =
@@ -87,7 +87,7 @@ public SqlServerSqlTranslatingExpressionVisitor(
         _queryCompilationContext = queryCompilationContext;
         _sqlExpressionFactory = dependencies.SqlExpressionFactory;
         _typeMappingSource = dependencies.TypeMappingSource;
-        _sqlServerCompatibilityLevel = sqlServerSingletonOptions.CompatibilityLevel;
+        _sqlServerSingletonOptions = sqlServerSingletonOptions;
     }
 
     /// <summary>
@@ -211,7 +211,9 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp
         // Translate non-aggregate string.Join to CONCAT_WS (for aggregate string.Join, see SqlServerStringAggregateMethodTranslator)
         if (method == StringJoinMethodInfo
             && methodCallExpression.Arguments[1] is NewArrayExpression newArrayExpression
-            && _sqlServerCompatibilityLevel >= 140)
+            && ((_sqlServerSingletonOptions.EngineType == SqlServerEngineType.SqlServer && _sqlServerSingletonOptions.SqlServerCompatibilityLevel >= 140)
+                || (_sqlServerSingletonOptions.EngineType == SqlServerEngineType.AzureSql && _sqlServerSingletonOptions.AzureSqlCompatibilityLevel >= 140)
+                || (_sqlServerSingletonOptions.EngineType == SqlServerEngineType.AzureSynapse)))
         {
             if (TranslationFailed(methodCallExpression.Arguments[0], Visit(methodCallExpression.Arguments[0]), out var delimiter))
             {
@@ -533,7 +535,13 @@ private static string EscapeLikePattern(string pattern)
     public override SqlExpression? GenerateGreatest(IReadOnlyList<SqlExpression> expressions, Type resultType)
     {
         // Docs: https://learn.microsoft.com/sql/t-sql/functions/logical-functions-greatest-transact-sql
-        if (_sqlServerCompatibilityLevel < 160)
+        if (_sqlServerSingletonOptions.EngineType == SqlServerEngineType.SqlServer
+            && _sqlServerSingletonOptions.SqlServerCompatibilityLevel < 160)
+        {
+            return null;
+        }
+        if (_sqlServerSingletonOptions.EngineType == SqlServerEngineType.AzureSql
+            && _sqlServerSingletonOptions.AzureSqlCompatibilityLevel < 160)
         {
             return null;
         }
@@ -555,7 +563,13 @@ private static string EscapeLikePattern(string pattern)
     public override SqlExpression? GenerateLeast(IReadOnlyList<SqlExpression> expressions, Type resultType)
     {
         // Docs: https://learn.microsoft.com/sql/t-sql/functions/logical-functions-least-transact-sql
-        if (_sqlServerCompatibilityLevel < 160)
+        if (_sqlServerSingletonOptions.EngineType == SqlServerEngineType.SqlServer
+            && _sqlServerSingletonOptions.SqlServerCompatibilityLevel < 160)
+        {
+            return null;
+        }
+        if (_sqlServerSingletonOptions.EngineType == SqlServerEngineType.AzureSql
+            && _sqlServerSingletonOptions.AzureSqlCompatibilityLevel < 160)
         {
             return null;
         }
diff --git a/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerStringMethodTranslator.cs b/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerStringMethodTranslator.cs
index 49064a8293d..f8dd1a44713 100644
--- a/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerStringMethodTranslator.cs
+++ b/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerStringMethodTranslator.cs
@@ -202,7 +202,9 @@ public SqlServerStringMethodTranslator(ISqlExpressionFactory sqlExpressionFactor
             // an overload that accepts the characters to trim.
             if (method == TrimStartMethodInfoWithoutArgs
                 || (method == TrimStartMethodInfoWithCharArrayArg && arguments[0] is SqlConstantExpression { Value: char[] { Length: 0 } })
-                || (_sqlServerSingletonOptions.CompatibilityLevel >= 160
+                || (((_sqlServerSingletonOptions.EngineType == SqlServerEngineType.SqlServer && _sqlServerSingletonOptions.SqlServerCompatibilityLevel >= 160)
+                        || (_sqlServerSingletonOptions.EngineType == SqlServerEngineType.AzureSql && _sqlServerSingletonOptions.AzureSqlCompatibilityLevel >= 160)
+                        || (_sqlServerSingletonOptions.EngineType == SqlServerEngineType.AzureSynapse))
                     && (method == TrimStartMethodInfoWithCharArg || method == TrimStartMethodInfoWithCharArrayArg)))
             {
                 return ProcessTrimStartEnd(instance, arguments, "LTRIM");
@@ -210,7 +212,9 @@ public SqlServerStringMethodTranslator(ISqlExpressionFactory sqlExpressionFactor
 
             if (method == TrimEndMethodInfoWithoutArgs
                 || (method == TrimEndMethodInfoWithCharArrayArg && arguments[0] is SqlConstantExpression { Value: char[] { Length: 0 } })
-                || (_sqlServerSingletonOptions.CompatibilityLevel >= 160
+                || (((_sqlServerSingletonOptions.EngineType == SqlServerEngineType.SqlServer && _sqlServerSingletonOptions.SqlServerCompatibilityLevel >= 160)
+                        || (_sqlServerSingletonOptions.EngineType == SqlServerEngineType.AzureSql && _sqlServerSingletonOptions.AzureSqlCompatibilityLevel >= 160)
+                        || (_sqlServerSingletonOptions.EngineType == SqlServerEngineType.AzureSynapse))
                     && (method == TrimEndMethodInfoWithCharArg || method == TrimEndMethodInfoWithCharArrayArg)))
             {
                 return ProcessTrimStartEnd(instance, arguments, "RTRIM");


Test patch:
diff --git a/test/EFCore.Design.Tests/Design/Internal/DbContextOperationsTest.cs b/test/EFCore.Design.Tests/Design/Internal/DbContextOperationsTest.cs
index 23375b644a6..68e7662ccef 100644
--- a/test/EFCore.Design.Tests/Design/Internal/DbContextOperationsTest.cs
+++ b/test/EFCore.Design.Tests/Design/Internal/DbContextOperationsTest.cs
@@ -270,7 +270,7 @@ public void GetContextInfo_returns_correct_info()
 
         Assert.Equal("Test", info.DatabaseName);
         Assert.Equal(@"(localdb)\mssqllocaldb", info.DataSource);
-        Assert.Equal("None", info.Options);
+        Assert.Equal("EngineType=SqlServer", info.Options);
         Assert.Equal("Microsoft.EntityFrameworkCore.SqlServer", info.ProviderName);
     }
 
@@ -291,7 +291,7 @@ public void GetContextInfo_does_not_throw_if_DbConnection_cannot_be_created()
 
         Assert.Equal(DesignStrings.BadConnection(expected.Message), info.DatabaseName);
         Assert.Equal(DesignStrings.BadConnection(expected.Message), info.DataSource);
-        Assert.Equal("None", info.Options);
+        Assert.Equal("EngineType=SqlServer", info.Options);
         Assert.Equal("Microsoft.EntityFrameworkCore.SqlServer", info.ProviderName);
     }
 
diff --git a/test/EFCore.SqlServer.FunctionalTests/LoggingSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/LoggingSqlServerTest.cs
index c73b6d512ae..64c82f18cdb 100644
--- a/test/EFCore.SqlServer.FunctionalTests/LoggingSqlServerTest.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/LoggingSqlServerTest.cs
@@ -61,4 +61,7 @@ protected override string ProviderName
     protected override string ProviderVersion
         => typeof(SqlServerOptionsExtension).Assembly
             .GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion;
+
+    protected override string DefaultOptions
+        => "EngineType=SqlServer ";
 }
diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServer160Test.cs b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServer160Test.cs
index ee806b4e0ab..c9f9b88881b 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServer160Test.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServer160Test.cs
@@ -4904,6 +4904,6 @@ protected override string StoreName
             => "ComplexNavigations160";
 
         public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder)
-            => base.AddOptions(builder).UseSqlServer(b => b.UseCompatibilityLevel(160));
+            => base.AddOptions(builder).UseSqlServer(b => b.UseSqlServerCompatibilityLevel(160));
     }
 }
diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServer160Test.cs b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServer160Test.cs
index 83800b92c3b..d58c957f986 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServer160Test.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServer160Test.cs
@@ -8526,6 +8526,6 @@ protected override string StoreName
             => "ComplexNavigationsOwned160";
 
         public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder)
-            => base.AddOptions(builder).UseSqlServer(b => b.UseCompatibilityLevel(160));
+            => base.AddOptions(builder).UseSqlServer(b => b.UseSqlServerCompatibilityLevel(160));
     }
 }
diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindDbFunctionsQuerySqlServer160Test.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindDbFunctionsQuerySqlServer160Test.cs
index c41575cf0ba..faaf2217203 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindDbFunctionsQuerySqlServer160Test.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindDbFunctionsQuerySqlServer160Test.cs
@@ -1467,6 +1467,6 @@ private void AssertSql(params string[] expected)
     public class Fixture160 : NorthwindQuerySqlServerFixture<NoopModelCustomizer>
     {
         public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder)
-            => base.AddOptions(builder).UseSqlServer(b => b.UseCompatibilityLevel(160));
+            => base.AddOptions(builder).UseSqlServer(b => b.UseSqlServerCompatibilityLevel(160));
     }
 }
diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindFunctionsQuerySqlServer160Test.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindFunctionsQuerySqlServer160Test.cs
index 555f1733719..6f0172d20f0 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindFunctionsQuerySqlServer160Test.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindFunctionsQuerySqlServer160Test.cs
@@ -3008,6 +3008,6 @@ protected override void ClearLog()
     public class Fixture160 : NorthwindQuerySqlServerFixture<NoopModelCustomizer>
     {
         public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder)
-            => base.AddOptions(builder).UseSqlServer(b => b.UseCompatibilityLevel(160));
+            => base.AddOptions(builder).UseSqlServer(b => b.UseSqlServerCompatibilityLevel(160));
     }
 }
diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/PrecompiledSqlPregenerationQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/PrecompiledSqlPregenerationQuerySqlServerTest.cs
index b187615aee8..93022636239 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Query/PrecompiledSqlPregenerationQuerySqlServerTest.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Query/PrecompiledSqlPregenerationQuerySqlServerTest.cs
@@ -258,7 +258,7 @@ public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder build
             // TODO: Figure out if there's a nice way to continue using the retrying strategy
             var sqlServerOptionsBuilder = new SqlServerDbContextOptionsBuilder(builder);
             sqlServerOptionsBuilder
-                .UseCompatibilityLevel(120)
+                .UseSqlServerCompatibilityLevel(120)
                 .ExecutionStrategy(d => new NonRetryingExecutionStrategy(d));
             return builder;
         }
diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQueryOldSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQueryOldSqlServerTest.cs
index 5877a8c7c14..92b57f0d64d 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQueryOldSqlServerTest.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQueryOldSqlServerTest.cs
@@ -1119,6 +1119,6 @@ protected override ITestStoreFactory TestStoreFactory
 
         // Compatibility level 120 (SQL Server 2014) doesn't support OPENJSON
         public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder)
-            => base.AddOptions(builder).UseSqlServer(o => o.UseCompatibilityLevel(120));
+            => base.AddOptions(builder).UseSqlServer(o => o.UseSqlServerCompatibilityLevel(120));
     }
 }
diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServer160Test.cs b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServer160Test.cs
index 09878bccedd..6d0e9f7bf9a 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServer160Test.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServer160Test.cs
@@ -1991,7 +1991,7 @@ protected override ITestStoreFactory TestStoreFactory
             => SqlServerTestStoreFactory.Instance;
 
         public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder)
-            => base.AddOptions(builder).UseSqlServer(b => b.UseCompatibilityLevel(160));
+            => base.AddOptions(builder).UseSqlServer(b => b.UseSqlServerCompatibilityLevel(160));
 
         protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context)
         {
diff --git a/test/EFCore.SqlServer.FunctionalTests/SqlServerConfigPatternsTest.cs b/test/EFCore.SqlServer.FunctionalTests/SqlServerConfigPatternsTest.cs
index d438844b951..26c498706f9 100644
--- a/test/EFCore.SqlServer.FunctionalTests/SqlServerConfigPatternsTest.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/SqlServerConfigPatternsTest.cs
@@ -424,16 +424,16 @@ public class AzureSqlDatabase
         [InlineData(true)]
         [InlineData(false)]
         [ConditionalTheory]
-        public void Retry_on_failure_not_enabled_by_default_on_Azure_SQL(bool configured)
+        public void Retry_on_failure_not_enabled_by_default_on_Azure_SQL(bool useAzure)
         {
-            using var context = new NorthwindContext(configured);
+            using var context = new NorthwindContext(useAzure);
 
             Assert.IsType<SqlServerExecutionStrategy>(context.Database.CreateExecutionStrategy());
         }
 
-        private class NorthwindContext(bool configured) : DbContext
+        private class NorthwindContext(bool useAzure) : DbContext
         {
-            private readonly bool _azureConfigured = configured;
+            private readonly bool _useAzure = useAzure;
 
             public DbSet<Customer> Customers { get; set; }
 
@@ -444,9 +444,11 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
                         @"Server=test.database.windows.net:4040;Database=Test;ConnectRetryCount=0",
                         a =>
                         {
-                            if (_azureConfigured)
+                            if (_useAzure)
                             {
+#pragma warning disable CS0618 // Type or member is obsolete
                                 a.UseAzureSqlDefaults(false);
+#pragma warning restore CS0618 // Type or member is obsolete
                             }
                         });
 
@@ -460,10 +462,10 @@ public class NonDefaultAzureSqlDatabase
         [InlineData(true)]
         [InlineData(false)]
         [ConditionalTheory]
-        public void Retry_on_failure_enabled_if_Azure_SQL_configured(bool configured)
+        public void Retry_on_failure_enabled_if_Azure_SQL_configured(bool useAzure)
         {
-            using var context = new NorthwindContext(configured);
-            if (configured)
+            using var context = new NorthwindContext(useAzure);
+            if (useAzure)
             {
                 Assert.IsType<SqlServerRetryingExecutionStrategy>(context.Database.CreateExecutionStrategy());
             }
@@ -473,24 +475,302 @@ public void Retry_on_failure_enabled_if_Azure_SQL_configured(bool configured)
             }
         }
 
-        private class NorthwindContext(bool azure) : DbContext
+        private class NorthwindContext(bool useAzure) : DbContext
         {
-            private readonly bool _isAzure = azure;
+            private readonly bool _useAzure = useAzure;
 
             public DbSet<Customer> Customers { get; set; }
 
             protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
-                => optionsBuilder
+            {
+                optionsBuilder
+                    .EnableServiceProviderCaching(false);
+                if (_useAzure)
+                {
+                    optionsBuilder
+                        .UseAzureSql(SqlServerNorthwindTestStoreFactory.NorthwindConnectionString);
+                }
+                else
+                {
+                    optionsBuilder
+                        .UseSqlServer(SqlServerNorthwindTestStoreFactory.NorthwindConnectionString);
+                }
+            }
+        }
+    }
+
+    public class ExplicitExecutionStrategies_SqlServer
+    {
+        [InlineData(true)]
+        [InlineData(false)]
+        [ConditionalTheory]
+        public void Retry_strategy_properly_handled(bool before)
+        {
+            using var context = new NorthwindContext(before);
+            if (before)
+            {
+                Assert.IsType<SqlServerRetryingExecutionStrategy>(context.Database.CreateExecutionStrategy());
+            }
+            else
+            {
+                Assert.IsType<DummyExecutionStrategy>(context.Database.CreateExecutionStrategy());
+            }
+        }
+
+        private class NorthwindContext(bool before) : DbContext
+        {
+            public DbSet<Customer> Customers { get; set; }
+
+            protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
+            {
+                optionsBuilder
                     .EnableServiceProviderCaching(false)
-                    .UseSqlServer(
-                        SqlServerNorthwindTestStoreFactory.NorthwindConnectionString,
-                        a =>
+                    .UseSqlServer(SqlServerNorthwindTestStoreFactory.NorthwindConnectionString,
+                        b =>
                         {
-                            if (_isAzure)
+                            if (before)
                             {
-                                a.UseAzureSqlDefaults();
+                                b.ExecutionStrategy(_ => new DummyExecutionStrategy());
+                            }
+                            b.EnableRetryOnFailure();
+                            if (!before)
+                            {
+                                b.ExecutionStrategy(_ => new DummyExecutionStrategy());
                             }
                         });
+            }
+
+            protected override void OnModelCreating(ModelBuilder modelBuilder)
+                => ConfigureModel(modelBuilder);
+        }
+    }
+    public class ExplicitExecutionStrategies_AzureSql
+    {
+        [InlineData(true)]
+        [InlineData(false)]
+        [ConditionalTheory]
+        public void Retry_strategy_properly_handled(bool before)
+        {
+            using var context = new NorthwindContext(before);
+            if (before)
+            {
+                Assert.IsType<SqlServerRetryingExecutionStrategy>(context.Database.CreateExecutionStrategy());
+            }
+            else
+            {
+                Assert.IsType<DummyExecutionStrategy>(context.Database.CreateExecutionStrategy());
+            }
+        }
+
+        private class NorthwindContext(bool before) : DbContext
+        {
+            public DbSet<Customer> Customers { get; set; }
+
+            protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
+            {
+                optionsBuilder
+                    .EnableServiceProviderCaching(false)
+                    .UseAzureSql(SqlServerNorthwindTestStoreFactory.NorthwindConnectionString,
+                        b =>
+                        {
+                            if (before)
+                            {
+                                b.ExecutionStrategy(_ => new DummyExecutionStrategy());
+                            }
+                            b.EnableRetryOnFailure();
+                            if (!before)
+                            {
+                                b.ExecutionStrategy(_ => new DummyExecutionStrategy());
+                            }
+                        });
+            }
+
+            protected override void OnModelCreating(ModelBuilder modelBuilder)
+                => ConfigureModel(modelBuilder);
+        }
+    }
+    public class ExplicitExecutionStrategies_AzureSynapse
+    {
+        [InlineData(true)]
+        [InlineData(false)]
+        [ConditionalTheory]
+        public void Retry_strategy_properly_handled(bool before)
+        {
+            using var context = new NorthwindContext(before);
+            if (before)
+            {
+                Assert.IsType<SqlServerRetryingExecutionStrategy>(context.Database.CreateExecutionStrategy());
+            }
+            else
+            {
+                Assert.IsType<DummyExecutionStrategy>(context.Database.CreateExecutionStrategy());
+            }
+        }
+
+        private class NorthwindContext(bool before) : DbContext
+        {
+            public DbSet<Customer> Customers { get; set; }
+
+            protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
+            {
+                optionsBuilder
+                    .EnableServiceProviderCaching(false)
+                    .UseAzureSynapse(SqlServerNorthwindTestStoreFactory.NorthwindConnectionString,
+                        b =>
+                        {
+                            if (before)
+                            {
+                                b.ExecutionStrategy(_ => new DummyExecutionStrategy());
+                            }
+                            b.EnableRetryOnFailure();
+                            if (!before)
+                            {
+                                b.ExecutionStrategy(_ => new DummyExecutionStrategy());
+                            }
+                        });
+            }
+
+            protected override void OnModelCreating(ModelBuilder modelBuilder)
+                => ConfigureModel(modelBuilder);
+        }
+    }
+    public class ExplicitExecutionStrategies_ConfigureSqlEngine_AzureSql
+    {
+        [InlineData(true)]
+        [InlineData(false)]
+        [ConditionalTheory]
+        public void Retry_strategy_properly_handled(bool before)
+        {
+            using var context = new NorthwindContext(before);
+            if (before)
+            {
+                Assert.IsType<SqlServerRetryingExecutionStrategy>(context.Database.CreateExecutionStrategy());
+            }
+            else
+            {
+                Assert.IsType<DummyExecutionStrategy>(context.Database.CreateExecutionStrategy());
+            }
+        }
+
+        private class NorthwindContext(bool before) : DbContext
+        {
+            public DbSet<Customer> Customers { get; set; }
+
+            protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
+            {
+                optionsBuilder
+                    .EnableServiceProviderCaching(false)
+                    .ConfigureSqlEngine(
+                        b =>
+                        {
+                            if (before)
+                            {
+                                b.ExecutionStrategy(_ => new DummyExecutionStrategy());
+                            }
+                            b.EnableRetryOnFailure();
+                            if (!before)
+                            {
+                                b.ExecutionStrategy(_ => new DummyExecutionStrategy());
+                            }
+                        })
+                    .UseAzureSql();
+            }
+
+            protected override void OnModelCreating(ModelBuilder modelBuilder)
+                => ConfigureModel(modelBuilder);
+        }
+    }
+
+    public class ConfigureTwoEngines
+    {
+        [Fact]
+        public void Throws_when_two_engines_used()
+        {
+            using var context = new NorthwindContext();
+            Assert.Throws<InvalidOperationException>(() => { _ = context.Model; });
+        }
+
+        private class NorthwindContext : DbContext
+        {
+            public DbSet<Customer> Customers { get; set; }
+
+            protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
+            {
+                optionsBuilder
+                    .EnableServiceProviderCaching(false)
+                    .UseSqlServer()
+                    .UseAzureSql();
+            }
+
+            protected override void OnModelCreating(ModelBuilder modelBuilder)
+                => ConfigureModel(modelBuilder);
+        }
+    }
+
+    public class NoEngineConfigured
+    {
+        [Fact]
+        public void Throws_when_no_engine_configured()
+        {
+            using var context = new NorthwindContext();
+            Assert.Throws<InvalidOperationException>(() => { _ = context.Model; });
+        }
+
+        private class NorthwindContext : DbContext
+        {
+            public DbSet<Customer> Customers { get; set; }
+
+            protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
+            {
+                optionsBuilder
+                    .EnableServiceProviderCaching(false)
+                    .ConfigureSqlEngine();
+            }
+
+            protected override void OnModelCreating(ModelBuilder modelBuilder)
+                => ConfigureModel(modelBuilder);
+        }
+    }
+
+    public class AddConfigureDbContext
+    {
+        [Fact]
+        public void Does_not_throw_for_Add_Configure()
+        {
+            using var scope = new ServiceCollection()
+                .AddDbContext<NorthwindContext>(b => b.UseSqlServer())
+                .ConfigureDbContext<NorthwindContext>(b => b.ConfigureSqlEngine(o => o.EnableRetryOnFailure()))
+                .BuildServiceProvider(validateScopes: true)
+                .CreateScope();
+
+            var serviceProvider = scope.ServiceProvider;
+
+            var exception = Record.Exception(serviceProvider.GetRequiredService<NorthwindContext>);
+            Assert.Null(exception);
+        }
+
+        [Fact]
+        public void Proper_execution_strategy()
+        {
+            using var scope = new ServiceCollection()
+                .AddDbContext<NorthwindContext>(b => b.UseSqlServer())
+                .ConfigureDbContext<NorthwindContext>(b => b.ConfigureSqlEngine(o => o.EnableRetryOnFailure()))
+                .BuildServiceProvider(validateScopes: true)
+                .CreateScope();
+
+            var serviceProvider = scope.ServiceProvider;
+
+            var context = serviceProvider.GetRequiredService<NorthwindContext>();
+            Assert.IsType<SqlServerRetryingExecutionStrategy>(context.Database.CreateExecutionStrategy());
+        }
+
+        private class NorthwindContext : DbContext
+        {
+            public DbSet<Customer> Customers { get; set; }
+
+            public NorthwindContext(DbContextOptions options)
+                : base(options)
+            { }
 
             protected override void OnModelCreating(ModelBuilder modelBuilder)
                 => ConfigureModel(modelBuilder);
@@ -516,4 +796,12 @@ private static void ConfigureModel(ModelBuilder builder)
                 b.HasKey(c => c.CustomerID);
                 b.ToTable("Customers");
             });
+
+    private class DummyExecutionStrategy : IExecutionStrategy
+    {
+        public bool RetriesOnFailure => true;
+
+        public TResult Execute<TState, TResult>(TState state, Func<DbContext, TState, TResult> operation, Func<DbContext, TState, ExecutionResult<TResult>> verifySucceeded) => throw new NotImplementedException();
+        public Task<TResult> ExecuteAsync<TState, TResult>(TState state, Func<DbContext, TState, CancellationToken, Task<TResult>> operation, Func<DbContext, TState, CancellationToken, Task<ExecutionResult<TResult>>> verifySucceeded, CancellationToken cancellationToken = default) => throw new NotImplementedException();
+    }
 }
diff --git a/test/EFCore.SqlServer.Tests/SqlServerOptionsExtensionTest.cs b/test/EFCore.SqlServer.Tests/SqlServerOptionsExtensionTest.cs
index e1de681c655..38db2102555 100644
--- a/test/EFCore.SqlServer.Tests/SqlServerOptionsExtensionTest.cs
+++ b/test/EFCore.SqlServer.Tests/SqlServerOptionsExtensionTest.cs
@@ -52,13 +52,16 @@ public static IModel Instance
     }
 
     [ConditionalFact]
-    public void ApplyServices_adds_SQL_server_services()
+    public void ApplyServices_adds_correct_services()
     {
         var services = new ServiceCollection();
 
-        new SqlServerOptionsExtension().ApplyServices(services);
+        new SqlServerOptionsExtension()
+            .WithEngineType(SqlServerEngineType.SqlServer)
+            .ApplyServices(services);
 
         Assert.Contains(services, sd => sd.ServiceType == typeof(ISqlServerConnection));
+        Assert.Contains(services, sd => sd.ServiceType == typeof(ISqlServerSingletonOptions));
     }
 
     private class ChangedRowNumberContext(bool setInternalServiceProvider) : DbContext