-
Notifications
You must be signed in to change notification settings - Fork 251
Milestone
Description
Running the following program:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.0-rc.1" />
<PackageReference Include="Npgsql.DependencyInjection" Version="8.0.0-preview.4" />
</ItemGroup>
</Project>using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
RunTest("Host=localhost;Database=test");
Console.WriteLine("First test passed");
RunTest("Host=myserver;Database=mydata");
Console.WriteLine("Second test passed");
static void RunTest(string connectionString)
{
var serviceCollection = new ServiceCollection();
serviceCollection.AddNpgsqlDataSource(connectionString);
serviceCollection.AddDbContext<TestDbContext>(builder => builder.UseNpgsql(connectionString));
var sp = serviceCollection.BuildServiceProvider();
var context = sp.GetRequiredService<TestDbContext>();
if (context.Database.GetDbConnection().ConnectionString != connectionString)
{
throw new Exception($"""
This is broken.
Expected: {connectionString}
Actual: {context.Database.GetDbConnection().ConnectionString}
""");
}
}
public class TestDbContext(DbContextOptions<TestDbContext> options) : DbContext(options) { }produces an error on the 2nd test run:
First test passed
Unhandled exception. System.Exception: This is broken.
Expected: Host=myserver;Database=mydata
Actual: Host=localhost;Database=test
at Program.<<Main>$>g__RunTest|0_0(String connectionString) in C:\Users\eerhardt\source\repos\ConsoleApp100\ConsoleApp100\Program.cs:line 22
at Program.<Main>$(String[] args) in C:\Users\eerhardt\source\repos\ConsoleApp100\ConsoleApp100\Program.cs:line 7
The connection string is reused across DI containers. As far as I can tell, it is because:
- EF uses the DbContextOptions as a cache key in here:
https://github.com/dotnet/efcore/blob/5299be3bfeab62224f29aae9d4adff510878fcf7/src/EFCore/Internal/ServiceProviderCache.cs#L68-L71 - DbContextOptions overrides Equals: https://github.com/dotnet/efcore/blob/5299be3bfeab62224f29aae9d4adff510878fcf7/src/EFCore/DbContextOptions.cs#L142-L147
So DbContextOptions between 2 different DbContexts equal, and the stuff cached for the first context (like theINpgsqlSingletonOptions) are being reused across different DI containers
cc @roji
DanSmith