-
Couldn't load subscription status.
- Fork 2k
Document ConfigureDbContext method and AddDbContext precedence changes in EF Core 8.0 #5118
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: live
Are you sure you want to change the base?
Changes from all commits
aed0fbb
3c2e6f2
fc3ce37
5d80627
c6277c3
e544d44
52ec51e
1072ea3
fc950c9
ce6de19
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,7 +2,7 @@ | |
| title: DbContext Lifetime, Configuration, and Initialization - EF Core | ||
| description: Patterns for creating and managing DbContext instances with or without dependency injection | ||
| author: SamMonoRT | ||
| ms.date: 11/07/2020 | ||
| ms.date: 09/30/2025 | ||
| uid: core/dbcontext-configuration/index | ||
| --- | ||
|
|
||
|
|
@@ -90,6 +90,75 @@ The final result is an `ApplicationDbContext` instance created for each request | |
|
|
||
| Read further in this article to learn more about configuration options. See [Dependency injection in ASP.NET Core](/aspnet/core/fundamentals/dependency-injection) for more information. | ||
|
|
||
| <a name="configuredbcontext"></a> | ||
|
|
||
| ## ConfigureDbContext for configuration composition | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This definitely doesn't seem like the first thing to document on this page, above "Basic DbContext initialization with 'new'". IIUC (and as documented), ConfigureDbContext is for reusable libraries/components (like Aspire), and so is not an end-user API. As such it maybe merits a short note at the very bottom, but nothing like this at the very top - this would confuse any beginner user coming here. (FWIW I don't remember any user requesting something like this for tests, as documented - this would have to be a very advanced/elaborate scenario. Even we've managed fine without it.) |
||
|
|
||
| Starting with EF Core 9.0, you can use <xref:Microsoft.Extensions.DependencyInjection.EntityFrameworkServiceCollectionExtensions.ConfigureDbContext*> to apply additional configuration to a `DbContext` either before or after the `AddDbContext` call. This is particularly useful for composing non-conflicting configuration in reusable components or tests. | ||
|
|
||
| ### Basic ConfigureDbContext usage | ||
|
|
||
| `ConfigureDbContext` allows you to add configuration in a reusable library or component without replacing the entire provider configuration: | ||
|
|
||
| <!-- | ||
| var services = new ServiceCollection(); | ||
|
|
||
| services.ConfigureDbContext<BlogContext>(options => | ||
| options.EnableSensitiveDataLogging() | ||
| .EnableDetailedErrors()); | ||
|
|
||
| services.AddDbContext<BlogContext>(options => | ||
| options.UseInMemoryDatabase("BasicExample")); | ||
|
|
||
| var serviceProvider = services.BuildServiceProvider(); | ||
| --> | ||
| [!code-csharp[BasicConfigureDbContext](../../../samples/core/Miscellaneous/ConfiguringDbContext/ConfigureDbContextSample.cs?name=BasicConfigureDbContext)] | ||
|
|
||
| ### Provider-specific configuration without connection strings | ||
|
|
||
| To apply provider-specific configuration you can use provider-specific configuration methods without supplying the connection string. The SQL Server provider also includes `ConfigureSqlEngine` for this case. See [SQL Server-specific batching behavior](xref:core/providers/sql-server/misc#configuresqlengine) for more information. | ||
|
|
||
| <!-- | ||
| var services = new ServiceCollection(); | ||
|
|
||
| services.ConfigureDbContext<BlogContext>(options => | ||
| options.UseSqlServer(sqlOptions => | ||
| sqlOptions.EnableRetryOnFailure())); | ||
|
|
||
| services.AddDbContext<BlogContext>(options => | ||
| options.UseSqlServer("connectionString")); | ||
|
|
||
| var serviceProvider = services.BuildServiceProvider(); | ||
| --> | ||
| [!code-csharp[ProviderSpecificConfiguration](../../../samples/core/Miscellaneous/ConfiguringDbContext/ConfigureDbContextSample.cs?name=ProviderSpecificConfiguration)] | ||
|
|
||
| ### ConfigureDbContext and AddDbContext precedence | ||
|
|
||
| When both `ConfigureDbContext` and `AddDbContext` are used, or when multiple calls to these methods are made, the configuration is applied in the order the methods are called, with later calls taking precedence for conflicting options. | ||
|
|
||
| For non-conflicting options (like adding logging, interceptors, or other settings), all configurations are composed together: | ||
|
|
||
| <!-- | ||
| var services = new ServiceCollection(); | ||
|
|
||
| services.ConfigureDbContext<BlogContext>(options => | ||
| options.LogTo(Console.WriteLine)); | ||
|
|
||
| services.AddDbContext<BlogContext>(options => | ||
| options.UseInMemoryDatabase("CompositionExample")); | ||
|
|
||
| services.ConfigureDbContext<BlogContext>(options => | ||
| options.EnableSensitiveDataLogging()); | ||
|
|
||
| var serviceProvider = services.BuildServiceProvider(); | ||
| --> | ||
| [!code-csharp[ConfigurationComposition](../../../samples/core/Miscellaneous/ConfiguringDbContext/ConfigureDbContextSample.cs?name=ConfigurationComposition)] | ||
|
|
||
| For conflicting options, the last configuration wins. See [breaking changes in EF Core 8.0](xref:core/what-is-new/ef-core-8.0/breaking-changes#AddDbContext) for more information about this behavior change. | ||
|
|
||
| > [!NOTE] | ||
| > Configuring a different provider will not remove the previous provider configuration. This can lead to errors when creating the context. To completely replace the provider, you need to remove the context registration and re-add it, or create a new service collection. | ||
|
|
||
| <!-- See also [Using Dependency Injection](TODO) for advanced dependency injection configuration with EF Core. --> | ||
|
|
||
| ## Basic DbContext initialization with 'new' | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,102 @@ | ||
| #nullable enable | ||
|
|
||
| using System; | ||
| using System.Linq; | ||
| using Microsoft.EntityFrameworkCore; | ||
| using Microsoft.Extensions.DependencyInjection; | ||
|
|
||
| namespace ConfigureDbContextSample; | ||
|
|
||
| public class BlogContext : DbContext | ||
| { | ||
| public BlogContext(DbContextOptions<BlogContext> options) : base(options) | ||
| { | ||
| } | ||
|
|
||
| public DbSet<Blog> Blogs => Set<Blog>(); | ||
| } | ||
|
|
||
| public class Blog | ||
| { | ||
| public int Id { get; set; } | ||
| public required string Title { get; set; } | ||
| public string? Content { get; set; } | ||
AndriySvyryd marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| public static class ConfigureDbContextSample | ||
| { | ||
| public static void Run() | ||
| { | ||
| BasicConfigureDbContextExample(); | ||
| ProviderSpecificConfigurationExample(); | ||
| ConfigurationCompositionExample(); | ||
| } | ||
|
|
||
| private static void BasicConfigureDbContextExample() | ||
| { | ||
| Console.WriteLine("=== Basic ConfigureDbContext Example ==="); | ||
|
|
||
| #region BasicConfigureDbContext | ||
| var services = new ServiceCollection(); | ||
|
|
||
| services.ConfigureDbContext<BlogContext>(options => | ||
| options.EnableSensitiveDataLogging() | ||
| .EnableDetailedErrors()); | ||
|
|
||
| services.AddDbContext<BlogContext>(options => | ||
| options.UseInMemoryDatabase("BasicExample")); | ||
| #endregion | ||
|
|
||
| var serviceProvider = services.BuildServiceProvider(); | ||
| using var scope = serviceProvider.CreateScope(); | ||
| var context = scope.ServiceProvider.GetRequiredService<BlogContext>(); | ||
|
|
||
| Console.WriteLine($"Context configured with provider: {context.Database.ProviderName}"); | ||
| Console.WriteLine(); | ||
| } | ||
|
|
||
| private static void ProviderSpecificConfigurationExample() | ||
| { | ||
| Console.WriteLine("=== Provider-Specific Configuration Example ==="); | ||
|
|
||
| #region ProviderSpecificConfiguration | ||
| var services = new ServiceCollection(); | ||
|
|
||
| services.ConfigureDbContext<BlogContext>(options => | ||
| options.UseSqlServer(sqlOptions => | ||
| sqlOptions.EnableRetryOnFailure())); | ||
|
|
||
| services.AddDbContext<BlogContext>(options => | ||
| options.UseSqlServer("connectionString")); | ||
| #endregion | ||
|
|
||
| var serviceProvider = services.BuildServiceProvider(); | ||
| Console.WriteLine("Provider-specific configuration applied"); | ||
| Console.WriteLine(); | ||
| } | ||
|
|
||
| private static void ConfigurationCompositionExample() | ||
| { | ||
| Console.WriteLine("=== Configuration Composition Example ==="); | ||
|
|
||
| #region ConfigurationComposition | ||
| var services = new ServiceCollection(); | ||
|
|
||
| services.ConfigureDbContext<BlogContext>(options => | ||
| options.LogTo(Console.WriteLine)); | ||
|
|
||
| services.AddDbContext<BlogContext>(options => | ||
| options.UseInMemoryDatabase("CompositionExample")); | ||
|
|
||
| services.ConfigureDbContext<BlogContext>(options => | ||
AndriySvyryd marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| options.EnableSensitiveDataLogging()); | ||
| #endregion | ||
|
|
||
| var serviceProvider = services.BuildServiceProvider(); | ||
| using var scope = serviceProvider.CreateScope(); | ||
| var context = scope.ServiceProvider.GetRequiredService<BlogContext>(); | ||
|
|
||
| Console.WriteLine($"Context configured with provider: {context.Database.ProviderName}"); | ||
| Console.WriteLine(); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,16 +1,19 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk.Web"> | ||
|
|
||
| <PropertyGroup> | ||
| <TargetFramework>net8.0</TargetFramework> | ||
| <TargetFramework>net9.0</TargetFramework> | ||
| <ImplicitUsings>enable</ImplicitUsings> | ||
| <RootNamespace /> | ||
| </PropertyGroup> | ||
|
|
||
| <ItemGroup> | ||
| <PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="8.0.0" /> | ||
| <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.0" /> | ||
| <PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="8.0.0" /> | ||
| <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.0" /> | ||
| <PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="9.0.0" /> | ||
| <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="9.0.0" /> | ||
| <PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="9.0.0" /> | ||
| <PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.0" /> | ||
AndriySvyryd marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| <PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="9.0.0" /> | ||
| <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.0" /> | ||
| <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.0" /> | ||
| </ItemGroup> | ||
|
|
||
| </Project> | ||
Uh oh!
There was an error while loading. Please reload this page.