Changing the connection string from an interceptor doesn't work from migrations
See https://github.com/dotnet/efcore/issues/31055
Just another simple console repro:
using System.Data.Common;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
await using TestContext context = new();
await context.Database.EnsureDeletedAsync();
await context.Database.EnsureCreatedAsync();
public class TestContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseNpgsql();
optionsBuilder.AddInterceptors(new ConnectionStringInitializationInterceptor(string.Empty));
base.OnConfiguring(optionsBuilder);
}
}
public class ConnectionStringInitializationInterceptor : DbConnectionInterceptor
{
private readonly string _connectionString;
internal ConnectionStringInitializationInterceptor(string connectionString)
{
_connectionString = connectionString;
}
public override InterceptionResult ConnectionOpening(DbConnection connection, ConnectionEventData eventData, InterceptionResult result)
{
if (string.IsNullOrEmpty(connection.ConnectionString))
{
connection.ConnectionString = _connectionString;
}
return result;
}
public async override ValueTask<InterceptionResult> ConnectionOpeningAsync(DbConnection connection, ConnectionEventData eventData, InterceptionResult result, CancellationToken cancellationToken = default)
{
if (string.IsNullOrEmpty(connection.ConnectionString))
{
connection.ConnectionString = _connectionString;
}
return result;
}
}
I'm not sure how far you've looked into this already, but to me it looks like there's some conflict of interest at this point.
When calling Exists inside of NpgsqlDatabaseCreator, the connection is enforced to be non-pooled.
This overwrites the empty string and lets the NpgsqlConnection throw when being cloned due to missing values.
So on one hand the ConnectionString has to be correctly configured, but on the other it should be empty to be passed to the interceptors.
@WhatzGames yeah, no, I haven't yet had any time to look at this - and it very well may be that the non-pooled change in EFCore.PG is the source of the issue. If that's really the problem, then it probably makes sense to specifically detect the empty string case and not rewrite?
@roji yeah, that's what I thought too.
But in that case either there has to be a way to apply the same changes after the interceptor has assigned a new ConnectionString, but before the connection is opened, or the developer is made responsible for making sure that the connection is not pooled.
Unless of course the non-pooled config is not absolutely necessary for the connection. In that case I'll happily just skip.
I'm experiencing this bug when running migrations in Aspire.