Entity Framework Core (EF Core) is a popular Object-Relational Mapping (ORM) framework in .NET applications, that allows developers to work with databases using C# objects. However, as applications scale and the need for data access increases, relying on direct database queries can lead to performance bottlenecks. To enhance performance and support scalability, it is important to implement a caching solution. NCache serves this purpose by providing distributed, in-memory caching as a second-level cache for EF Core.
Key Takeaways
Solving the Database Bottleneck: While EF Core is a powerful ORM, relying on direct database queries at scale creates performance limits. NCache resolves this by acting as a distributed, in-memory Second-Level Cache.
Beyond First-Level Caching: Unlike EF Core’s built-in first-level cache, which is restricted to a single DbContext instance, NCache provides a shared cache that persists across multiple application instances and sessions.
Minimal Code Integration: NCache integrates into existing LINQ queries using the FromCache() extension method, allowing developers to implement query caching without significant alterations to their application logic.
Automated Data Consistency: By using Database Dependencies (such as SQL Server), NCache ensures data integrity by automatically invalidating cached items whenever the underlying database data is modified.
Understanding Caching in EF Core
EF Core provides various caching mechanisms designed to enhance database query performance. Understanding the difference between first-level and second-level caching is essential for developing an effective caching strategy.
Comparison of Database Synchronization Strategies
| Feature | EF Core First-Level Cache | NCache (Second-Level Cache) |
|---|---|---|
| Storage Location | Internal to the DbContext instance |
Distributed In-Memory (External to DbContext) |
| Availability | Restricted to a single session/request | Shared across all sessions and app instances |
| Lifetime | Disposed with the DbContext |
Configurable (Absolute or Sliding Expiration) |
| Multi-Server Support | No (Local to one process) | Yes (Cluster-aware across server farms) |
| Consistency | Managed manually within the session | Automated via Database Dependencies |
- First-Level Caching
EF Core inherently implements first-level caching, which is limited to the lifecycle of a DbContext instance. This means that:
- Data retrieved during the lifespan of DbContext is cached in-memory.
- The cache is cleared when the DbContext instance is disposed of.
- Each DbContext instance maintains its own distinct cache, which prevents data sharing between different instances.
- The primary advantage of first-level caching is that it improves performance within a single DbContext session, but it does not retain data across multiple database calls outside of that context.
- Second-Level Caching
Second-level caching is essential for applications that require shared and persistent caching across various DbContext instances and even multiple application instances. Moreover, this type of caching retains frequently accessed data in a separate, shared cache, which significantly reduces database queries and enhances response times.
- Unlike first-level caching, second-level caching is independent of any single DbContext instance.
- It facilitates the caching of data beyond the lifespan of a DbContext, allowing different instances to utilize cached data.
- This caching mechanism is particularly helpful in distributed systems, where minimizing direct database calls can improve scalability and performance.
Why Use NCache for EF Core Caching?
NCache is a high-performance, distributed caching solution tailored for .NET applications. According to Microsoft’s EF Core best practices, offloading read-heavy workloads to a distributed cache is the most effective way to scale .NET data layers. Hence, when integrated alongside EF Core, it provides several advantages:
- Performance Enhancement – It minimizes database trips by serving cached query results.
- Seamless Integration – It integrates with EF Core without requiring major alterations to the application code.
- Scalability – Its distributed caching architecture guarantees optimal performance in high-traffic environments.
- Flexible Caching Policies – It allows customization of cache dependencies, expiration, and storage strategies.
Setting Up NCache as a Second-Level Cache for EF Core
To configure NCache for EF Core caching, follow these steps:
Step 1: Install the NCache EF Core Provider
Add the required NCache package to your project using NuGet:
|
1 |
Install-Package EntityFrameworkCore.NCache –Version x.x.x |
This package enables EF Core to leverage NCache for caching query results.
Step 2: Configure NCache in Your Application
Modify the DbContext configuration to enable NCache caching.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
[Serializable] public class Product { public int ProductId { get; set; } public string Name { get; set; } public string Category { get; set; } } public class ApplicationDbContext : DbContext { protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { string cacheId = "myCache"; var options = new CacheConnectionOptions(); NCacheConfiguration.Configure(cacheId, DependencyType.SqlServer, options); optionsBuilder.UseSqlServer("YourConnectionString"); } } |
This configuration allows caching with SQL Server database dependency, ensuring data consistency between the cache and the database.
Step 3: Using NCache for Query Caching
NCache offers the FromCache() extension method, ensuring seamless caching of EF Core queries.
|
1 2 3 4 5 6 7 8 |
// Step 3: Use the FromCache extension method to cache query results using (var context = new ApplicationDbContext()) { var products = context.Products .Where(p => p.Category == "Electronics") .FromCache(); // Checks NCache first; if miss, fetches from DB and populates cache } |
When available, data is accessed from the cache using the FromCache() method. Otherwise, it is fetched from the database and stored in the cache for future queries.
Step 4: Configuring Advanced Caching Options
NCache offers detailed management of caching behavior using CachingOptions.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
var options = new CachingOptions { StoreAs = StoreAs.SeparateEntities, Priority = CacheItemPriority.High, CreateDbDependency = true }; using (var context = new ApplicationDbContext()) { var products = context.Products .Where(p => p.Category == "Electronics") .FromCache(options); } |
In this example, every product is individually cached with a high priority, and a database dependency is established to ensure cache invalidation whenever there are changes to the underlying data.
Logging and Monitoring NCache Caching in EF Core
NCache offers logging features that help in monitoring cache behavior and troubleshooting potential issues.
|
1 |
NCacheConfiguration.EnableLogging("log.txt"); |
Enabling logging helps monitor cache hits, misses, and enhancements of query performance. By analyzing these logs, developers can identify cache-hit ratios and fine-tune expiration policies to further optimize the data access layer.
Conclusion
Integrating NCache as a second-level cache in EF Core significantly boosts application performance. By utilizing query caching, the load on the database reduces, accelerating data retrieval, and improving scalability. For large-scale, high-performance applications, leveraging NCache’s distributed caching capabilities ensures seamless and efficient database interaction.
For more detailed instructions and configurations, refer to the NCache EF Core documentation.
Frequently Asked Questions (FAQ)
Q: What is the difference between First-Level and Second-Level caching in EF Core?
A: First-Level caching is built-in to EF Core but is restricted to the lifecycle of a single DbContext instance. Second-Level caching, provided by NCache, is independent of the DbContext, allowing cached data to be shared across multiple application instances and persist beyond a single session.
Q: Does NCache require significant code changes to implement EF Core caching?
A: No. NCache integrates into your existing application using the FromCache() extension method. This allows you to enable caching for your LINQ queries with minimal alterations to your original source code.
Q: How does NCache ensure that cached EF Core data does not become stale?
A: NCache maintains data consistency by using Database Dependencies (such as SQL Server Dependency). This feature automatically invalidates or removes items from the cache whenever the underlying data in the database is modified, ensuring your application always works with fresh data.
Q: Can I control the caching behavior for specific EF Core queries?
A: Yes. By using the CachingOptions class, you can define granular policies for each query, such as setting the cache priority, choosing how entities are stored (e.g., StoreAs.SeparateEntities), and enabling or disabling database synchronizations.







Good article, Usually I used the Azure Cache for Redis to achieves the superior throughput and latency performance by storing data in memory instead of on disk. In terms of pricing very cheap and in terms of performance it adds a great value to response time.
Anyway, a great effort to explain the complex topic in plain word.