efcore icon indicating copy to clipboard operation
efcore copied to clipboard

Add UseNetTopologySuite extension method for AzureSqlDbContextOptionsBuilder

Open jscarle opened this issue 1 year ago • 1 comments

As part of https://github.com/dotnet/efcore/issues/33816, UseAzureSql was introduced, however it seems like it's not possible to combine UseAzureSql with UseNetTopologySuite.

With UseSqlServer, we'd typically do:

                options.UseSqlServer(connectionString, sqlServerOptions =>
                {
                    sqlServerOptions.UseNetTopologySuite();
                });

There does not seem to be an equivalent. This does not work:

                options.UseAzureSql(connectionString, azureSqlOptions =>
                {
                    azureSqlOptions.UseNetTopologySuite();
                });

It appears that all we'd need is to add the following:

    public static AzureSqlDbContextOptionsBuilder UseNetTopologySuite(
        this AzureSqlDbContextOptionsBuilder optionsBuilder)
    {
        var coreOptionsBuilder = ((IRelationalDbContextOptionsBuilderInfrastructure)optionsBuilder).OptionsBuilder;

        var extension = coreOptionsBuilder.Options.FindExtension<SqlServerNetTopologySuiteOptionsExtension>()
                        ?? new SqlServerNetTopologySuiteOptionsExtension();

        ((IDbContextOptionsBuilderInfrastructure)coreOptionsBuilder).AddOrUpdateExtension(extension);

        return optionsBuilder;
    }

to SqlServerNetTopologySuiteDbContextOptionsBuilderExtensions

jscarle avatar Dec 01 '24 00:12 jscarle

Confirmed, UseNetTopologySuite() (and other plugin activation methods) is defined over SqlServerDbContextOptionsBuilder, but AzureSqlDbContextOptionsBuilder doesn't extend that (original PR: #34385).

roji avatar Dec 01 '24 11:12 roji

SqlEngineDbContextOptionsBuilder base class. Move UseNetTopologySuite to base.

cincuranet avatar Sep 08 '25 17:09 cincuranet

As it turns out we already have SqlEngineDbContextOptionsBuilder (used when calling ConfigureSqlEngine). Does SqlEngineDbContextOptionsBuilderBase sound good as an alternative? SqlServerDbContextOptionsBuilderBase does not sound bad either (SqlServer because the whole package is called EFCore.SqlServer), but it might be bit confusing.

cincuranet avatar Sep 10 '25 08:09 cincuranet

SqlEngineDbContextOptionsBuilder sounds fine to me (especially if it already exists...)

roji avatar Sep 10 '25 09:09 roji

We can't use SqlEngineDbContextOptionsBuilder because it already exists and (intentionally) SQL Server, Azure SQL, Synapse builders do not derive from it.

cincuranet avatar Sep 10 '25 09:09 cincuranet

Ah sorry, I read too fast. Do you recall why we intentionally didn't derive the concrete builders from this one?

Otherwise, in general I don't think the name of the builder type is too important (users aren't confronted with it). I do prefer SqlEngine to SqlServer for something that's general to all database types (just like we already have SqlEngineDbContextOptionsBuilder). So I guess SqlEngineDbContextOptionsBuilderBase is fine.

roji avatar Sep 10 '25 09:09 roji

IIRC the reasoning was that even i.e. UseCompatibilityLevel does not have the same meaning (including different defaults) between i.e. SQL Server and Synapse and hence there's no value in having a base class.

cincuranet avatar Sep 10 '25 10:09 cincuranet

Ah, looking at the code I also see that RelationalDbContextOptionsBuilder takes as an type parameter concrete class (i.e. RelationalDbContextOptionsBuilder<AzureSynapseDbContextOptionsBuilder, SqlServerOptionsExtension>) hence base class has no value in here (of course, the type parameter can be passed).

cincuranet avatar Sep 10 '25 10:09 cincuranet