CachedQueries 2.0.0
dotnet add package CachedQueries --version 2.0.0
NuGet\Install-Package CachedQueries -Version 2.0.0
<PackageReference Include="CachedQueries" Version="2.0.0" />
paket add CachedQueries --version 2.0.0
#r "nuget: CachedQueries, 2.0.0"
// Install CachedQueries as a Cake Addin #addin nuget:?package=CachedQueries&version=2.0.0 // Install CachedQueries as a Cake Tool #tool nuget:?package=CachedQueries&version=2.0.0
CachedQueries: Efficient Caching for Entity Framework Queries
Introduction
CachedQueries is a .NET library designed to seamlessly integrate caching into Entity Framework (EF) queries. It simplifies caching IQueryable results directly within EF, removing the need for additional layers, while ensuring efficient data retrieval and cache invalidation.
Installation
To install CachedQueries, run the following command:
dotnet add package CachedQueries
Setup and Configuration
- Configure Dependency Injection:
// Add system cache
services.AddMemoryCache();
// Add CachedQueries
services.AddQueriesCaching(options =>
options
.UseCacheStore<MemoryCache>() // Configure cache store
.UseEntityFramework() // Integrate with EF
);
// Activate caching in your application
app.UseQueriesCaching();
- Cache Invalidation in EF Context:
To automatically invalidate cache entries when data changes, extend your EF context:
// Override SaveChanges and SaveChangesAsync methods in EF context
public override async Task<int> SaveChangesAsync(CancellationToken token = default)
{
await ChangeTracker.ExpireEntitiesCacheAsync(token); // Trigger cache invalidation
return await base.SaveChangesAsync(token);
}
Basic Usage
Caching Queries
Cache collections or individual entities with optional expiration:
// Cache collections
var orders = await context.Orders
.Include(b => b.Items)
.ToListCachedAsync(cancellationToken);
// Set custom expiration (e.g., 4 hours)
var customers = await context.Customers
.ToListCachedAsync(new CachingOptions(TimeSpan.FromHours(4)), cancellationToken);
// Cache single entity
var product = await context.Products
.FirstOrDefaultCachedAsync(b => b.Id == request.Id, cancellationToken);
Manual Cache Invalidation
Manually control cache invalidation with custom tags:
// Initialize cache invalidator
private ICacheInvalidator _cacheInvalidator;
// Invalidate cache with tags
await _cacheInvalidator.InvalidateCacheAsync(new List<string> { "custom_tag" });
Distributed Caching with Redis
For distributed environments, you can use Redis as your caching solution:
// Add Redis distributed cache
services.AddStackExchangeRedisCache(config);
// Configure CachedQueries with Redis
services.AddQueriesCaching(options =>
options
.UseCacheStore<DistributedCache>() // Use distributed cache
.UseEntityFramework() // Integrate with EF
);
Advanced Configuration
CachedQueries offers flexible configuration options, allowing you to customize various components:
Custom Cache Stores
You can implement your own cache store by providing a class that implements the ICacheStore interface. This allows you to manage caching according to your custom rules, including data storage and retrieval.
// Custom cache store implementation
services.AddQueriesCaching(options =>
options
.UseCacheStore<CustomCacheStore>() // Custom ICacheStore implementation
.UseEntityFramework());
Custom Cache Invalidators
To control when and how cached data is invalidated, you can implement a custom cache invalidator. This is useful for scenarios where invalidation needs to follow specific business rules or depend on external conditions.
// Custom cache invalidator setup
services.AddQueriesCaching(options =>
options
.UseCacheInvalidator<CustomCacheInvalidator>() // Custom ICacheInvalidator implementation
.UseEntityFramework());
Cache Strategies
You can define custom strategies for both caching collections and individual entries. CachedQueries enables you to specify how data is stored, retrieved, and expired.
Cache Collection Strategy: Manages the caching behavior for collections, such as lists or arrays of entities.
Cache Entry Strategy: Manages the caching behavior for individual entities.
To implement custom strategies, provide classes that inherit from ICacheCollectionStrategy
and ICacheEntryStrategy
.
// Custom cache strategies setup
services.AddQueriesCaching(options =>
options
.UseCacheCollectionStrategy<CustomCollectionStrategy>() // Custom ICacheCollectionStrategy implementation
.UseCacheEntryStrategy<CustomEntryStrategy>() // Custom ICacheEntryStrategy implementation
.UseEntityFramework());
Cache Key Factory
The cache key factory determines how cache keys are generated. CachedQueries allows you to define custom key generation logic, which can be useful if your application has unique keying requirements for different types of queries.
// Custom cache key factory setup
services.AddQueriesCaching(options =>
options
.UseKeyFactory<CustomKeyFactory>() // Custom ICacheKeyFactory implementation
.UseEntityFramework());
Custom Cache Context Provider
CachedQueries allows for the use of a custom ICacheContextProvider
to manage context-specific caching. This is useful when cache keys need to be unique across different contexts, such as tenants, users, or environments.
// Example of a custom cache context provider
public class TenantCacheContextProvider : ICacheContextProvider
{
private readonly IHttpContextAccessor _httpContextAccessor;
public TenantCacheContextProvider(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
public string GetContextKey()
{
// Example: Use tenant ID from the HTTP context
return _httpContextAccessor.HttpContext?.User?.FindFirst("tenant_id")?.Value ?? "default_tenant";
}
}
Setup a custom cache context provider:
// Custom cache key factory setup
services.AddQueriesCaching(options =>
options
.UseCacheContextProvider<TenantCacheContextProvider>()
.UseEntityFramework());
Custom Dependency Injection Example
Here's an example of how you can configure CachedQueries with various custom strategies and services:
services.AddQueriesCaching(options =>
options
.UseCacheStore<CustomCacheStore>() // Custom cache store
.UseCacheInvalidator<CustomCacheInvalidator>() // Custom invalidator
.UseCacheCollectionStrategy<CustomCollectionStrategy>() // Custom collection strategy
.UseCacheEntryStrategy<CustomEntryStrategy>() // Custom entry strategy
.UseKeyFactory<CustomKeyFactory>() // Custom key factory
.UseCacheContextProvider<CustomContextProvider>()
.UseOptions(new CacheOptions
{
DefaultExpiration = TimeSpan.FromMinutes(30),
})
.UseEntityFramework());
Conclusion
CachedQueries is designed to streamline caching within your Entity Framework queries, offering a highly customizable framework for optimizing data access. With support for custom stores, strategies, key factories, and invalidators, it can be extended to meet complex caching requirements.
To dive deeper into the functionality and explore more advanced examples, check the library’s test cases and example project in ./examples
.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
-
net8.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
2.0.0 | 1,600 | 10/18/2024 |
1.0.18 | 2,640 | 7/5/2024 |
1.0.17 | 334 | 2/7/2023 |
1.0.16 | 74,368 | 1/31/2023 |
1.0.15 | 655 | 1/29/2023 |
1.0.14 | 1,104 | 1/25/2023 |
1.0.13 | 3,849 | 1/5/2023 |
1.0.12 | 4,381 | 12/7/2022 |
1.0.11 | 6,663 | 10/21/2022 |
1.0.10 | 11,213 | 7/14/2022 |
1.0.9 | 1,977 | 7/1/2022 |
1.0.8 | 425 | 7/1/2022 |
1.0.7 | 430 | 7/1/2022 |
1.0.6 | 12,021 | 4/11/2022 |
1.0.5 | 1,865 | 3/4/2022 |
1.0.4 | 734 | 2/24/2022 |
1.0.3 | 433 | 2/22/2022 |
1.0.2 | 436 | 2/22/2022 |
1.0.1 | 499 | 2/22/2022 |
1.0.0 | 536 | 2/22/2022 |