From 792d56439a5127398c908d0a419051556faecd31 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 26 Sep 2025 20:15:38 +0000 Subject: [PATCH 01/10] Initial plan From 1014d1c1d4b4305f0cf81ef4bf044b387000c089 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 26 Sep 2025 20:21:05 +0000 Subject: [PATCH 02/10] Add comprehensive UseMemoryCache documentation Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com> --- .../core/dbcontext-configuration/index.md | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/entity-framework/core/dbcontext-configuration/index.md b/entity-framework/core/dbcontext-configuration/index.md index 55d3738ccb..e28ccc75f8 100644 --- a/entity-framework/core/dbcontext-configuration/index.md +++ b/entity-framework/core/dbcontext-configuration/index.md @@ -309,6 +309,7 @@ The following table contains examples of common methods called on `DbContextOpti | | More detailed query errors (at the expense of performance) | [Logging, Events, and Diagnostics](xref:core/logging-events-diagnostics/index) | | Ignore or throw for warnings and other events | [Logging, Events, and Diagnostics](xref:core/logging-events-diagnostics/index) | | Registers EF Core interceptors | [Logging, Events, and Diagnostics](xref:core/logging-events-diagnostics/index) +| | Controls caching of the internal service provider | [Service Provider Caching](#service-provider-caching) | | Use dynamic proxies for lazy-loading | [Lazy Loading](xref:core/querying/related-data/lazy) | | Use dynamic proxies for change-tracking | Coming soon... @@ -423,6 +424,114 @@ Any code that explicitly executes multiple threads in parallel should ensure tha Using dependency injection, this can be achieved by either registering the context as scoped, and creating scopes (using `IServiceScopeFactory`) for each thread, or by registering the `DbContext` as transient (using the overload of `AddDbContext` which takes a `ServiceLifetime` parameter). +## Service Provider Caching + +EF Core uses an internal service provider to manage services required for database operations, including query compilation, model building, and other core functionality. By default, EF Core caches these internal service providers to improve performance when multiple `DbContext` instances share the same configuration. + +### EnableServiceProviderCaching + +The method controls whether EF Core caches the internal service provider: + + +[!code-csharp[EnableServiceProviderCaching](../../../samples/core/Miscellaneous/CompiledModels/BlogsContext.cs?range=18-22&highlight=2)] + +**Default behavior**: Service provider caching is **enabled by default** (`true`). This means: +- Service providers are cached and reused across `DbContext` instances with the same configuration +- Better performance for applications that create many `DbContext` instances +- Lower memory overhead when multiple contexts share configurations + +**When to disable caching**: You might want to disable service provider caching (`false`) in these scenarios: +- **Testing environments**: To ensure each test gets a fresh service provider +- **Compiled models**: When using [compiled models](xref:core/performance/advanced-performance-topics#compiled-models), caching may not provide benefits +- **Dynamic configurations**: When `DbContext` configurations change dynamically at runtime +- **Memory-sensitive applications**: When you want to minimize memory usage and don't mind the performance cost + +### Memory Cache Integration + +EF Core integrates with ASP.NET Core's memory caching infrastructure through `IMemoryCache`. This is separate from the internal service provider caching described above. + +#### EF Core 3.0+ Memory Cache Changes + +Starting with EF Core 3.0, there were important changes to how memory caching is handled: + +**AddDbContext and Memory Cache**: Prior to EF Core 3.0, calling `AddDbContext` or `AddDbContextPool` automatically registered `IMemoryCache` services. Starting with EF Core 3.0, these methods no longer automatically call `AddMemoryCache()`. + +**If your application needs `IMemoryCache`**, you must explicitly register it: + +```csharp +public void ConfigureServices(IServiceCollection services) +{ + services.AddMemoryCache(); // Explicit registration required in EF Core 3.0+ + services.AddDbContext(options => + options.UseSqlServer(connectionString)); +} +``` + +**AddEntityFramework* Methods**: The `AddEntityFramework*` methods (like `AddEntityFrameworkSqlServer`) now register `IMemoryCache` with a size limit to prevent unbounded memory growth: + +```csharp +public void ConfigureServices(IServiceCollection services) +{ + // This automatically registers IMemoryCache with size limits + services.AddEntityFrameworkSqlServer(); + + // Or register your own IMemoryCache implementation beforehand + services.AddMemoryCache(options => + { + options.SizeLimit = 1000; // Custom size limit + }); + services.AddEntityFrameworkSqlServer(); +} +``` + +### Performance Considerations + +**Service Provider Caching Performance Impact**: +- **Enabled (default)**: Faster `DbContext` creation, lower memory usage for multiple instances +- **Disabled**: Slower `DbContext` creation, but more predictable memory usage + +**Memory Cache Performance Impact**: +- EF Core uses `IMemoryCache` for various internal caching operations +- Query plan caching relies on memory caching infrastructure +- Without proper memory cache configuration, you may experience degraded performance + +### Best Practices + +1. **Keep service provider caching enabled** unless you have a specific reason to disable it +2. **Explicitly register `IMemoryCache`** in EF Core 3.0+ applications that need it +3. **Configure memory cache size limits** to prevent unbounded memory growth +4. **Disable service provider caching in tests** to ensure isolation between test runs +5. **Monitor memory usage** in applications with dynamic configurations + +### Example: Configuring Both Caching Options + +```csharp +public void ConfigureServices(IServiceCollection services) +{ + // Configure memory cache with size limit + services.AddMemoryCache(options => + { + options.SizeLimit = 1000; + options.CompactionPercentage = 0.25; + }); + + services.AddDbContext(options => + options + .UseSqlServer(connectionString) + .EnableServiceProviderCaching(true)); // Default, but shown for clarity +} +``` + ## More reading - Read [Dependency Injection](/aspnet/core/fundamentals/dependency-injection) to learn more about using DI. From 6019d54f8944c8e820d12bcc2a9405fc55139fd2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 26 Sep 2025 20:24:03 +0000 Subject: [PATCH 03/10] Add comprehensive memory cache configuration sample Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com> --- .../CachingConfiguration.csproj | 15 ++ .../CachingConfiguration/Program.cs | 180 ++++++++++++++++++ .../CachingConfiguration/README.md | 38 ++++ 3 files changed, 233 insertions(+) create mode 100644 samples/core/Miscellaneous/CachingConfiguration/CachingConfiguration.csproj create mode 100644 samples/core/Miscellaneous/CachingConfiguration/Program.cs create mode 100644 samples/core/Miscellaneous/CachingConfiguration/README.md diff --git a/samples/core/Miscellaneous/CachingConfiguration/CachingConfiguration.csproj b/samples/core/Miscellaneous/CachingConfiguration/CachingConfiguration.csproj new file mode 100644 index 0000000000..a210f53c1f --- /dev/null +++ b/samples/core/Miscellaneous/CachingConfiguration/CachingConfiguration.csproj @@ -0,0 +1,15 @@ + + + + Exe + net8.0 + enable + + + + + + + + + \ No newline at end of file diff --git a/samples/core/Miscellaneous/CachingConfiguration/Program.cs b/samples/core/Miscellaneous/CachingConfiguration/Program.cs new file mode 100644 index 0000000000..0419247206 --- /dev/null +++ b/samples/core/Miscellaneous/CachingConfiguration/Program.cs @@ -0,0 +1,180 @@ +using System; +using System.Collections.Generic; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; + +namespace CachingConfiguration; + +class Program +{ + static void Main() + { + Console.WriteLine("=== EF Core Memory Cache Configuration Examples ===\n"); + + // Example 1: Service Provider Caching (Default behavior) + ServiceProviderCachingExample(); + + // Example 2: Disable Service Provider Caching + DisableServiceProviderCachingExample(); + + // Example 3: ASP.NET Core with Memory Cache + AspNetCoreMemoryCacheExample(); + + // Example 4: Performance comparison + PerformanceComparisonExample(); + } + + static void ServiceProviderCachingExample() + { + Console.WriteLine("1. Service Provider Caching (Default - Enabled)"); + Console.WriteLine("================================================"); + + // Create multiple contexts with same configuration + // Service providers will be cached and reused + var context1 = new BlogContextWithCaching(); + var context2 = new BlogContextWithCaching(); + + Console.WriteLine($"Context 1 created: {context1.GetHashCode()}"); + Console.WriteLine($"Context 2 created: {context2.GetHashCode()}"); + Console.WriteLine("Service providers are cached and reused for same configuration\n"); + + context1.Dispose(); + context2.Dispose(); + } + + static void DisableServiceProviderCachingExample() + { + Console.WriteLine("2. Service Provider Caching Disabled"); + Console.WriteLine("===================================="); + + // Create contexts with caching disabled + // Each context gets its own service provider + var context1 = new BlogContextNoCaching(); + var context2 = new BlogContextNoCaching(); + + Console.WriteLine($"Context 1 created: {context1.GetHashCode()}"); + Console.WriteLine($"Context 2 created: {context2.GetHashCode()}"); + Console.WriteLine("Each context has its own service provider (no caching)\n"); + + context1.Dispose(); + context2.Dispose(); + } + + static void AspNetCoreMemoryCacheExample() + { + Console.WriteLine("3. ASP.NET Core Memory Cache Configuration"); + Console.WriteLine("=========================================="); + + var services = new ServiceCollection(); + + // Register memory cache with custom configuration + services.AddMemoryCache(options => + { + options.SizeLimit = 1000; + options.CompactionPercentage = 0.25; + }); + + // Register DbContext with explicit memory cache + services.AddDbContext(options => + options.UseInMemoryDatabase("TestDb") + .EnableServiceProviderCaching(true) // Default, shown for clarity + .LogTo(Console.WriteLine, LogLevel.Information)); + + var serviceProvider = services.BuildServiceProvider(); + using var scope = serviceProvider.CreateScope(); + + var context = scope.ServiceProvider.GetRequiredService(); + var memoryCache = scope.ServiceProvider.GetRequiredService(); + + Console.WriteLine($"DbContext created: {context.GetType().Name}"); + Console.WriteLine($"Memory cache available: {memoryCache != null}"); + Console.WriteLine("Memory cache is configured with size limit of 1000\n"); + } + + static void PerformanceComparisonExample() + { + Console.WriteLine("4. Performance Comparison"); + Console.WriteLine("========================="); + + const int iterations = 1000; + + // Test with caching enabled + var sw = System.Diagnostics.Stopwatch.StartNew(); + for (int i = 0; i < iterations; i++) + { + using var context = new BlogContextWithCaching(); + // Simulate some work + _ = context.Model; + } + sw.Stop(); + var cachedTime = sw.ElapsedMilliseconds; + + // Test with caching disabled + sw.Restart(); + for (int i = 0; i < iterations; i++) + { + using var context = new BlogContextNoCaching(); + // Simulate some work + _ = context.Model; + } + sw.Stop(); + var noCacheTime = sw.ElapsedMilliseconds; + + Console.WriteLine($"Time with service provider caching: {cachedTime}ms"); + Console.WriteLine($"Time without service provider caching: {noCacheTime}ms"); + Console.WriteLine($"Performance improvement: {((double)noCacheTime / cachedTime):F1}x faster\n"); + } +} + +// Context with default caching (enabled) +public class BlogContextWithCaching : DbContext +{ + public DbSet Blogs => Set(); + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + optionsBuilder + .UseInMemoryDatabase("CachedDb") + .EnableServiceProviderCaching(true); // Default behavior, explicit for clarity + } +} + +// Context with caching disabled +public class BlogContextNoCaching : DbContext +{ + public DbSet Blogs => Set(); + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + optionsBuilder + .UseInMemoryDatabase("NoCacheDb") + .EnableServiceProviderCaching(false); // Explicitly disable caching + } +} + +// Base context for DI scenarios +public class BlogContext : DbContext +{ + public BlogContext(DbContextOptions options) : base(options) + { + } + + public DbSet Blogs => Set(); +} + +public class Blog +{ + public int Id { get; set; } + public string Title { get; set; } = null!; + public List Posts { get; set; } = new(); +} + +public class Post +{ + public int Id { get; set; } + public string Content { get; set; } = null!; + public int BlogId { get; set; } + public Blog Blog { get; set; } = null!; +} \ No newline at end of file diff --git a/samples/core/Miscellaneous/CachingConfiguration/README.md b/samples/core/Miscellaneous/CachingConfiguration/README.md new file mode 100644 index 0000000000..65650d0e6e --- /dev/null +++ b/samples/core/Miscellaneous/CachingConfiguration/README.md @@ -0,0 +1,38 @@ +# EF Core Caching Configuration Sample + +This sample demonstrates various aspects of memory caching and service provider caching in Entity Framework Core. + +## What This Sample Shows + +1. **Service Provider Caching (Default)**: How EF Core caches internal service providers for better performance +2. **Disabled Service Provider Caching**: When and how to disable caching for specific scenarios +3. **ASP.NET Core Memory Cache Integration**: How to configure `IMemoryCache` with EF Core in dependency injection scenarios +4. **Performance Comparison**: Demonstrating the performance impact of service provider caching + +## Key Concepts Demonstrated + +### EnableServiceProviderCaching + +- **Default**: `true` (enabled) - Service providers are cached and reused +- **When to disable**: Testing scenarios, compiled models, dynamic configurations +- **Performance impact**: Significant improvement when enabled for multiple context instances + +### Memory Cache Integration + +- EF Core 3.0+ requires explicit `AddMemoryCache()` registration +- `AddEntityFramework*` methods register `IMemoryCache` with size limits +- Proper configuration prevents unbounded memory growth + +## Running the Sample + +```bash +dotnet run +``` + +The sample will output performance comparisons and demonstrate different caching behaviors. + +## Related Documentation + +- [DbContext Configuration](../../core/dbcontext-configuration/index.md#service-provider-caching) +- [EF Core Performance](../../core/performance/index.md) +- [EF Core 3.0 Breaking Changes](../../core/what-is-new/ef-core-3.x/breaking-changes.md#addentityframework-adds-imemorycache-with-a-size-limit) \ No newline at end of file From 2c3e7ec61504171d702d5531a423801815115711 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 27 Sep 2025 00:51:56 +0000 Subject: [PATCH 04/10] Address review feedback on memory cache documentation Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com> --- .../core/dbcontext-configuration/index.md | 69 +------ .../CachingConfiguration.csproj | 15 -- .../CachingConfiguration/Program.cs | 180 ------------------ .../CachingConfiguration/README.md | 38 ---- 4 files changed, 10 insertions(+), 292 deletions(-) delete mode 100644 samples/core/Miscellaneous/CachingConfiguration/CachingConfiguration.csproj delete mode 100644 samples/core/Miscellaneous/CachingConfiguration/Program.cs delete mode 100644 samples/core/Miscellaneous/CachingConfiguration/README.md diff --git a/entity-framework/core/dbcontext-configuration/index.md b/entity-framework/core/dbcontext-configuration/index.md index e28ccc75f8..77b164126f 100644 --- a/entity-framework/core/dbcontext-configuration/index.md +++ b/entity-framework/core/dbcontext-configuration/index.md @@ -452,83 +452,34 @@ The (options => - options.UseSqlServer(connectionString)); -} -``` - -**AddEntityFramework* Methods**: The `AddEntityFramework*` methods (like `AddEntityFrameworkSqlServer`) now register `IMemoryCache` with a size limit to prevent unbounded memory growth: - -```csharp -public void ConfigureServices(IServiceCollection services) -{ - // This automatically registers IMemoryCache with size limits - services.AddEntityFrameworkSqlServer(); - - // Or register your own IMemoryCache implementation beforehand - services.AddMemoryCache(options => - { - options.SizeLimit = 1000; // Custom size limit - }); - services.AddEntityFrameworkSqlServer(); + options + .UseSqlServer(connectionString) + .EnableServiceProviderCaching(true)); // Default, but shown for clarity } ``` -### Performance Considerations - -**Service Provider Caching Performance Impact**: -- **Enabled (default)**: Faster `DbContext` creation, lower memory usage for multiple instances -- **Disabled**: Slower `DbContext` creation, but more predictable memory usage - -**Memory Cache Performance Impact**: -- EF Core uses `IMemoryCache` for various internal caching operations -- Query plan caching relies on memory caching infrastructure -- Without proper memory cache configuration, you may experience degraded performance - -### Best Practices +### Memory Cache Integration -1. **Keep service provider caching enabled** unless you have a specific reason to disable it -2. **Explicitly register `IMemoryCache`** in EF Core 3.0+ applications that need it -3. **Configure memory cache size limits** to prevent unbounded memory growth -4. **Disable service provider caching in tests** to ensure isolation between test runs -5. **Monitor memory usage** in applications with dynamic configurations +EF Core integrates with ASP.NET Core's memory caching infrastructure through `IMemoryCache`. However, this is not used for the internal service provider caching described above. -### Example: Configuring Both Caching Options +EF Core automatically configures `IMemoryCache` with a default size limit of 10240 for internal caching operations such as query compilation and model building. You should call `AddMemoryCache` if you need to change these defaults. For reference, a compiled query has a cache size of 10, while the built model has a cache size of 100. ```csharp public void ConfigureServices(IServiceCollection services) { - // Configure memory cache with size limit services.AddMemoryCache(options => { - options.SizeLimit = 1000; - options.CompactionPercentage = 0.25; + options.SizeLimit = 20480; // Custom size limit for EF Core caching }); - + services.AddDbContext(options => - options - .UseSqlServer(connectionString) - .EnableServiceProviderCaching(true)); // Default, but shown for clarity + options.UseSqlServer(connectionString)); } ``` diff --git a/samples/core/Miscellaneous/CachingConfiguration/CachingConfiguration.csproj b/samples/core/Miscellaneous/CachingConfiguration/CachingConfiguration.csproj deleted file mode 100644 index a210f53c1f..0000000000 --- a/samples/core/Miscellaneous/CachingConfiguration/CachingConfiguration.csproj +++ /dev/null @@ -1,15 +0,0 @@ - - - - Exe - net8.0 - enable - - - - - - - - - \ No newline at end of file diff --git a/samples/core/Miscellaneous/CachingConfiguration/Program.cs b/samples/core/Miscellaneous/CachingConfiguration/Program.cs deleted file mode 100644 index 0419247206..0000000000 --- a/samples/core/Miscellaneous/CachingConfiguration/Program.cs +++ /dev/null @@ -1,180 +0,0 @@ -using System; -using System.Collections.Generic; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Caching.Memory; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; - -namespace CachingConfiguration; - -class Program -{ - static void Main() - { - Console.WriteLine("=== EF Core Memory Cache Configuration Examples ===\n"); - - // Example 1: Service Provider Caching (Default behavior) - ServiceProviderCachingExample(); - - // Example 2: Disable Service Provider Caching - DisableServiceProviderCachingExample(); - - // Example 3: ASP.NET Core with Memory Cache - AspNetCoreMemoryCacheExample(); - - // Example 4: Performance comparison - PerformanceComparisonExample(); - } - - static void ServiceProviderCachingExample() - { - Console.WriteLine("1. Service Provider Caching (Default - Enabled)"); - Console.WriteLine("================================================"); - - // Create multiple contexts with same configuration - // Service providers will be cached and reused - var context1 = new BlogContextWithCaching(); - var context2 = new BlogContextWithCaching(); - - Console.WriteLine($"Context 1 created: {context1.GetHashCode()}"); - Console.WriteLine($"Context 2 created: {context2.GetHashCode()}"); - Console.WriteLine("Service providers are cached and reused for same configuration\n"); - - context1.Dispose(); - context2.Dispose(); - } - - static void DisableServiceProviderCachingExample() - { - Console.WriteLine("2. Service Provider Caching Disabled"); - Console.WriteLine("===================================="); - - // Create contexts with caching disabled - // Each context gets its own service provider - var context1 = new BlogContextNoCaching(); - var context2 = new BlogContextNoCaching(); - - Console.WriteLine($"Context 1 created: {context1.GetHashCode()}"); - Console.WriteLine($"Context 2 created: {context2.GetHashCode()}"); - Console.WriteLine("Each context has its own service provider (no caching)\n"); - - context1.Dispose(); - context2.Dispose(); - } - - static void AspNetCoreMemoryCacheExample() - { - Console.WriteLine("3. ASP.NET Core Memory Cache Configuration"); - Console.WriteLine("=========================================="); - - var services = new ServiceCollection(); - - // Register memory cache with custom configuration - services.AddMemoryCache(options => - { - options.SizeLimit = 1000; - options.CompactionPercentage = 0.25; - }); - - // Register DbContext with explicit memory cache - services.AddDbContext(options => - options.UseInMemoryDatabase("TestDb") - .EnableServiceProviderCaching(true) // Default, shown for clarity - .LogTo(Console.WriteLine, LogLevel.Information)); - - var serviceProvider = services.BuildServiceProvider(); - using var scope = serviceProvider.CreateScope(); - - var context = scope.ServiceProvider.GetRequiredService(); - var memoryCache = scope.ServiceProvider.GetRequiredService(); - - Console.WriteLine($"DbContext created: {context.GetType().Name}"); - Console.WriteLine($"Memory cache available: {memoryCache != null}"); - Console.WriteLine("Memory cache is configured with size limit of 1000\n"); - } - - static void PerformanceComparisonExample() - { - Console.WriteLine("4. Performance Comparison"); - Console.WriteLine("========================="); - - const int iterations = 1000; - - // Test with caching enabled - var sw = System.Diagnostics.Stopwatch.StartNew(); - for (int i = 0; i < iterations; i++) - { - using var context = new BlogContextWithCaching(); - // Simulate some work - _ = context.Model; - } - sw.Stop(); - var cachedTime = sw.ElapsedMilliseconds; - - // Test with caching disabled - sw.Restart(); - for (int i = 0; i < iterations; i++) - { - using var context = new BlogContextNoCaching(); - // Simulate some work - _ = context.Model; - } - sw.Stop(); - var noCacheTime = sw.ElapsedMilliseconds; - - Console.WriteLine($"Time with service provider caching: {cachedTime}ms"); - Console.WriteLine($"Time without service provider caching: {noCacheTime}ms"); - Console.WriteLine($"Performance improvement: {((double)noCacheTime / cachedTime):F1}x faster\n"); - } -} - -// Context with default caching (enabled) -public class BlogContextWithCaching : DbContext -{ - public DbSet Blogs => Set(); - - protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - { - optionsBuilder - .UseInMemoryDatabase("CachedDb") - .EnableServiceProviderCaching(true); // Default behavior, explicit for clarity - } -} - -// Context with caching disabled -public class BlogContextNoCaching : DbContext -{ - public DbSet Blogs => Set(); - - protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - { - optionsBuilder - .UseInMemoryDatabase("NoCacheDb") - .EnableServiceProviderCaching(false); // Explicitly disable caching - } -} - -// Base context for DI scenarios -public class BlogContext : DbContext -{ - public BlogContext(DbContextOptions options) : base(options) - { - } - - public DbSet Blogs => Set(); -} - -public class Blog -{ - public int Id { get; set; } - public string Title { get; set; } = null!; - public List Posts { get; set; } = new(); -} - -public class Post -{ - public int Id { get; set; } - public string Content { get; set; } = null!; - public int BlogId { get; set; } - public Blog Blog { get; set; } = null!; -} \ No newline at end of file diff --git a/samples/core/Miscellaneous/CachingConfiguration/README.md b/samples/core/Miscellaneous/CachingConfiguration/README.md deleted file mode 100644 index 65650d0e6e..0000000000 --- a/samples/core/Miscellaneous/CachingConfiguration/README.md +++ /dev/null @@ -1,38 +0,0 @@ -# EF Core Caching Configuration Sample - -This sample demonstrates various aspects of memory caching and service provider caching in Entity Framework Core. - -## What This Sample Shows - -1. **Service Provider Caching (Default)**: How EF Core caches internal service providers for better performance -2. **Disabled Service Provider Caching**: When and how to disable caching for specific scenarios -3. **ASP.NET Core Memory Cache Integration**: How to configure `IMemoryCache` with EF Core in dependency injection scenarios -4. **Performance Comparison**: Demonstrating the performance impact of service provider caching - -## Key Concepts Demonstrated - -### EnableServiceProviderCaching - -- **Default**: `true` (enabled) - Service providers are cached and reused -- **When to disable**: Testing scenarios, compiled models, dynamic configurations -- **Performance impact**: Significant improvement when enabled for multiple context instances - -### Memory Cache Integration - -- EF Core 3.0+ requires explicit `AddMemoryCache()` registration -- `AddEntityFramework*` methods register `IMemoryCache` with size limits -- Proper configuration prevents unbounded memory growth - -## Running the Sample - -```bash -dotnet run -``` - -The sample will output performance comparisons and demonstrate different caching behaviors. - -## Related Documentation - -- [DbContext Configuration](../../core/dbcontext-configuration/index.md#service-provider-caching) -- [EF Core Performance](../../core/performance/index.md) -- [EF Core 3.0 Breaking Changes](../../core/what-is-new/ef-core-3.x/breaking-changes.md#addentityframework-adds-imemorycache-with-a-size-limit) \ No newline at end of file From 6320f7007de1c0c5c1291608154d7d22cddc25f0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 27 Sep 2025 02:00:38 +0000 Subject: [PATCH 05/10] Address additional review feedback on documentation structure Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com> --- entity-framework/core/dbcontext-configuration/index.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/entity-framework/core/dbcontext-configuration/index.md b/entity-framework/core/dbcontext-configuration/index.md index 77b164126f..19f3621646 100644 --- a/entity-framework/core/dbcontext-configuration/index.md +++ b/entity-framework/core/dbcontext-configuration/index.md @@ -310,6 +310,7 @@ The following table contains examples of common methods called on `DbContextOpti | | Ignore or throw for warnings and other events | [Logging, Events, and Diagnostics](xref:core/logging-events-diagnostics/index) | | Registers EF Core interceptors | [Logging, Events, and Diagnostics](xref:core/logging-events-diagnostics/index) | | Controls caching of the internal service provider | [Service Provider Caching](#service-provider-caching) +| | Configures the memory cache used by EF Core | [Memory Cache Integration](#memory-cache-integration) | | Use dynamic proxies for lazy-loading | [Lazy Loading](xref:core/querying/related-data/lazy) | | Use dynamic proxies for change-tracking | Coming soon... @@ -451,8 +452,7 @@ The Date: Sat, 27 Sep 2025 02:08:05 +0000 Subject: [PATCH 06/10] Fix documentation structure and markdown linting errors Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com> --- entity-framework/core/dbcontext-configuration/index.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/entity-framework/core/dbcontext-configuration/index.md b/entity-framework/core/dbcontext-configuration/index.md index 19f3621646..bdaab4d353 100644 --- a/entity-framework/core/dbcontext-configuration/index.md +++ b/entity-framework/core/dbcontext-configuration/index.md @@ -425,12 +425,10 @@ Any code that explicitly executes multiple threads in parallel should ensure tha Using dependency injection, this can be achieved by either registering the context as scoped, and creating scopes (using `IServiceScopeFactory`) for each thread, or by registering the `DbContext` as transient (using the overload of `AddDbContext` which takes a `ServiceLifetime` parameter). -## Service Provider Caching +## EnableServiceProviderCaching EF Core uses an internal service provider to manage services required for database operations, including query compilation, model building, and other core functionality. By default, EF Core caches these internal service providers to improve performance when multiple `DbContext` instances share the same configuration. -### EnableServiceProviderCaching - The method controls whether EF Core caches the internal service provider: -[!code-csharp[EnableServiceProviderCaching](../../../samples/core/Miscellaneous/CompiledModels/BlogsContext.cs?range=18-22&highlight=2)] +} +``` **Default behavior**: Service provider caching is **enabled by default** (`true`). This means: