Synchronizing EF Core Results using FromCache
The FromCache method caches the result set data generated against the LINQ query and returns it to the application. If the data doesn't exist in the cache, it will be fetched from the data source and stored in the cache. If the application makes the same query again, it will get the necessary data from the cache, avoiding an unnecessary trip to the data source. Thus, the FromCache method gives you consistent results for your data by synchronizing the distributed cache with the database result set just after executing your first query.
However, since this method takes place on two levels (getting the result set data and updating the cache), there is an increased chance of failure, especially in the latter case. You may fail to update the cache due to a variety of reasons. For instance, database connection failure, network error, the cache/server being down, a failure to serialize the data, a state transfer scenario, etc.
Therefore, NCache provides users employing FromCache with the errorEnabled allows them to determine whether they want to stop the application for any non-result-set-related issues. Generally, if caching and system performance are a priority, users will set this flag to True (as the query deals with the data source every time, otherwise). However, if their priority is preventing the application from stopping, users will set this flag to False.
Note
By default, the errorEnabled flag is set to False.
Note
Even if the errorEnabled flag is False, these updating cache-related exceptions will be logged in the Cache logs available at %NCHome%/log-files.
Prerequisites
- Install the following NuGet packages in your client application:
- Enterprise: EntityFrameworkCore.NCache
- OpenSource: EntityFrameworkCore.NCache.OpenSource
- Include the following namespaces in your application:
- The cache must be running.
- Make sure that the data being added is serializable.
- For API details, refer to: CachingOptions, StoreAs, FromCache, FromCacheAsync.
Implementation Examples for FromCache
- The following example fetches customer details based on a specified customer ID from the database and stores them as a separate entity in cache with specified caching options.
using (var context = new NorthwindContext())
{
var options = new CachingOptions
{
StoreAs = StoreAs.SeparateEntities
};
var resultSet = (from cust in context.Customers
where cust.CustomerId == someCustomerId
select cust).FromCache(options).ToList();
}
Note
To ensure the operation is fail-safe, it is recommended to handle any potential exceptions within your application, as explained in Handling Failures.
Note
You can also monitor the activity of your cache using the NCache Monitor.
- The following example returns the cache key generated internally against the query result set data stored as a collection in the cache. This key can be saved for future usage like removing the entity/result set from cache.
using (var context = new NorthwindContext())
{
var options = new CachingOptions
{
StoreAs = StoreAs.Collection
};
var resultSet = (from cust in context.Customers
where cust.CustomerId == someCustomerId
select cust).FromCache(out string cacheKey, options);
}
Note
By using Export-CacheKeys in the tool of your choice, you can view the cache keys of a particular cache.
Considerations for FromCache
FromCache supports the following functions:
Group ByOrder By AscendingOrder By DescendingSumMinMaxAverageCountContainsLikeFirstOrDefault
The functions can be implemented while using LINQ with FromCache, as follows:
- The
Likeoperator in EF Core performs pattern matching within character strings. Usually, it is employed withWhereinSELECTstatements to filter rows based on specific patterns or substrings within a column's value. Additionally, it allows the use of wildcards to match one or more characters in a string:
using (var context = new NorthwindContext())
{
var result = context.Customers
.Where(c => EF.Functions.Like(c.CompanyName, "Alfreds Futterkiste"))
.FromCache(options)
.ToList();
}
- The
Containsoperator can be used similarly to theLikeoperator to employ pattern-based searches within a given criteria.
using (var context = new NorthwindContext())
{
var result = context.Customers
.Where(b => (b.CompanyName.Contains("Alfreds Futterkist")))
.FromCache(out cacheKey, options)
}
- The
FirstOrDefaultoperator can be implemented as demonstrated below.
using (var context = new NorthwindContext())
{
var result = context.Products
.Where(b => b.UnitPrice > 1)
.FromCache(out cacheKey, options)
.FirstOrDefault();
}
- The
GroupBycan be used with projection for FromCache as implemented below.
using (var context = new NorthwindContext())
{
var resultSet = context.Products
.Where(p => p.UnitPrice == 10)
.GroupBy(p => p.ProductName)
.Select(group => group.Key)
.FromCache(out cacheKey, options)
.ToList();
}
Implementing Asynchronous LINQ APIs
The asynchronous APIs have the same functionality as their synchronous counterparts, but with asynchronous behavior. The parameters passed to these methods are also the same.
Important
Due to its asynchronous nature, cacheKey is not returned in any of the asynchronous calls like FromCacheAsync as out parameters are not allowed with methods with async signature.
FromCacheAsync
Data is directly fetched from the database if cache connection establishment fails. However, after every 60 seconds of the request being made, the cache connection is retried. The subsequent requests will try to reinitialize the cache after 60 seconds of the last request. Whenever a connection is successfully established, the data is fetched from the cache.
The following example fetches customer details based on a specified customer ID from the database asynchronously and stores them as a separate entity in the cache with specified caching options.
using (var context = new NorthwindContext())
{
var options = new CachingOptions
{
StoreAs = StoreAs.SeparateEntities
};
var task = (from cust in context.Customers
where cust.CustomerId == someCustomerId
select cust).FromCacheAsync(options);
task.Wait();
var resultSet = task.Result.ToList();
}
See Also
.NET: Alachisoft.NCache.EntityFrameworkCore namespace.
.NET: Alachisoft.NCache.Runtime.Caching namespace.