• Webinars
  • Docs
  • Download
  • Blogs
  • Contact Us
Try Free
Show / Hide Table of Contents

EF Core Extension Methods

NCache provides synchronous and asynchronous extension methods for caching queries in EF Core. The sync APIs are extension methods provided on IQueryable interface while the Async APIs are respective invocations of the sync APIs. The Async APIs return a task instance for these methods.

To utilize the following APIs, include the following namespace in your application: Alachisoft.NCache.EntityFrameworkCore

NCache’s Entity Framework Core Caching Provider contains the following APIs for caching queries:

Synchronous APIs Asynchronous APis
FromCache FromCacheAsync
LoadIntoCache LoadIntoCacheAsync
FromCacheOnly FromCacheOnlyAsync

FromCache

Note

This feature is available in NCache Enterprise and Professional editions.

The FromCache method caches the result set generated against the LINQ query and returns it upon call. In case the data is not present in the cache, it will be fetched from the data source and stored in the cache. Upon subsequent execution of the same query, the result will be fetched from the cache.

If the cache connection cannot be made, the data will be directly fetched from the database. However, after every 60 seconds of the request made, cache connection will be retried. The subsequent requests will try to re-initialize the cache after 60 seconds of the last request. Whenever the cache connection is successfully established, the data will then be fetched from the cache. This also applies to the FromCacheAsync method.

FromCache is highly efficient for execution of advanced LINQ queries requiring more flexibility, and result sets that are used periodically. For example, customer details can be cached as they are infrequently changed, however customer orders can be updated regularly.

Examples

  • 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.SeperateEntities
    };

    var resultSet = (from cust in context.Customers
                     where cust.CustomerId == someCustomerId
                     select cust).FromCache(options).ToList();
}


  • The following example returns the cache key internally generated against the query result set which is stored as a collection in the cache. This key can be saved for future usage purposes 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);
}

LoadIntoCache

Note

This feature is available in NCache Enterprise and Professional editions.

The LoadIntoCache API is useful for cases where fresh data from the database is cached every time the method is called. This fetches a result set from the source and caches it before returning it. Upon executing the same query again, the result will be fetched from the source and cached again – meaning existing cache data is overwritten every time. This is useful as any subsequent FromCache calls will also yield fresh data. In case the cache is not initialized, an exception message is thrown.

The LoadIntoCache method is particularly suitable for data that is frequently updated like customer orders or any sensitive data like payment details. In such scenarios, using stale data can result in incorrect business transactions, hence a fresh copy of the data must be present in the cache at all times.

Examples

  • The following example fetches the customer orders from the database and loads the result set into the cache as a collection. It also returns the cache key generated internally which can be saved for future use.
using (var context = new NorthwindContext())
{
    var options = new CachingOptions
    {
        StoreAs = StoreAs.Collection
    };

    var resultSet = (from custOrder in context.Orders
                     where custOrder.Customer.CustomerId == someCustomerId
                     select custOrder)).LoadIntoCache(out string cacheKey, options);
}


  • The following example loads the specific order details from the database into the cache as separate entities with caching options specified.
using (var context = new NorthwindContext())
{
    var options = new CachingOptions
    {
        StoreAs = StoreAs.SeperateEntities
    };

    var resultSet = (from custOrder in context.Orders
                     where custOrder.Customer.CustomerId == someCustomerId
                     select custOrder)).LoadIntoCache(options);
}

FromCacheOnly

Note

This feature is only available in NCache Enterprise edition.

For queries which have less frequent updates like customer details, regularly fetching such data from the data source is costly. Hence, performance can be enhanced by storing entities as separate entities. FromCacheOnly only queries the entities existing in cache and does not approach the data source in any case. If the entity exists in the cache, the result set will be returned for all subsequent FromCacheOnly() calls directly from the cache. If the entity does not exist in the cache, it will still not be fetched from the data source, and the LoadIntoCache or FromCache call can be made to load the result set into the cache. In case the cache is not initialized, an exception message is thrown.

Note

This API only works when entities are stored separately, i.e. the caching option StoreAs is set to SeperateEntities.

It is recommended to cache infrequently changing data as separate entities, as separate entities can be made part of multiple queries. Using FromCacheOnly, you can query data whose identifiers you are not aware of but have a criterion against which they can be queried while adhering to the limitations of FromCacheOnly discussed later in this topic.

Important

The entities MUST be indexed in NCache Web Manager before they are used with FromCacheOnly.

  • The following example fetches the customer information from the cache if the Customer entity exists. If not, the result set returned will be empty.
using (var context = new NorthwindContext())
{
    var resultSet = (from cust in context.Customers
                     where cust.CustomerId == someCustomerId
                     select cust).FromCacheOnly();
}

Limitations of FromCacheOnly

FromCacheOnly supports aggregate functions. However, these are immediate functions whose result is cached, and not the entities themselves. Hence, NCache has provided QueryDeferred which defers the query to resolve so the entities in the cache are queried to get the result. For more details on deferred APIs, please refer to the chapter Query Deferred APIs. The following functions are supported by FromCacheOnly:

  • Group By
  • Order By Ascending
  • Order By Descending
  • Select with Group By only
  • Sum
  • Min
  • Max
  • Average
  • Count

Keep in mind the following limitations regarding using LINQ in FromCacheOnly:

  • Except for Count, all aggregate functions need to be provided with integer values. Count needs to be provided with an entity to count.

  • More than one aggregate function cannot be used in a single LINQ expression for FromCacheOnly.

  • Projection in LINQ expressions for FromCacheOnly API can only be performed if a GroupBy operator and an aggregate function is used.

  • Multiple projections are not supported. Only one attribute can be projected in a LINQ expression (that is carried forward).

using (var context = new NorthwindContext())
{
    var min = context.Employees
        .Select(e => e.EmployeeId)  // Multiple projections have not been performed
        .GroupBy(eid => eid)        // eId was projected so GroupBy had to be used
        .DeferredMin()              // MIN provided with a numeric attribute
        .FromCacheOnly();
}
  • GroupBy can only be used if projection has been done beforehand on the attribute and an aggregate function is being used. GroupBy has to be the last operator in the LINQ expression except if OrderBy is used.

    • In such cases, the GroupBy function can be shifted forward (after OrderBy) or backward (before OrderBy).
using (var context = new NorthwindContext())
{

    var min = context.Employees
        .Select(e => e.EmployeeId)  // Multiple projections have not been performed
        .GroupBy(eid => eid)        // eId was projected so GroupBy had to be used
        .OrderBy(eid => eid)        // OrderBy can be used when GroupBy is used
        .DeferredMin()              //  MIN provided with a numeric attribute
        .FromCacheOnly();
}
  • OrderBy (both ascending and descending) can only be used in a LINQ expression for FromCacheOnly if GroupBy is used.

  • More than one GroupBy and OrderBy operators cannot be used in a single LINQ expression for FromCacheOnly.

  • Joins are not supported so the Include() method will not work.

  • For LINQ expressions containing DateTime instances, it is important that all nodes in a cache cluster have the same DateTime format set up. Otherwise, a format exception will be thrown. This problem arises when DateTime.Now and DateTime.Parse() are used in a multi node cache cluster. To avoid it, synchronize the DateTime format on both machines. Moreover, it is advised to use DateTime.ParseExact() over DateTime.Parse() as the ParseExact() API restricts the user to specify a format for DateTime.

Asynchronous LINQ APIs

The asynchronous APIs perform 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 and LoadIntoCacheAsync as out parameters are not allowed with methods with async signature.

FromCacheAsync

If the cache connection cannot be established, the data is directly fetched from the database. However, after every 60 seconds of the request made, cache connection is retried. The subsequent requests will try to re-initialize the cache after 60 seconds of the last request. Whenever the cache connection is successfully established, the data will then be 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 cache with specified caching options.

using (var context = new NorthwindContext())
{
    var options = new CachingOptions
    {
        StoreAs = StoreAs.SeperateEntities
    };

    var task = (from cust in context.Customers
                where cust.CustomerId == someCustomerId
                select cust).FromCacheAsync(options);
    task.Wait();
    var resultSet = task.Result.ToList();
}

LoadIntoCacheAsync

The following example loads the specific order details from the database into the cache as separate entities with caching options specified.

using (var context = new NorthwindContext())
{
    var options = new CachingOptions
    {
        StoreAs = StoreAs.SeperateEntities
    };

    var task = (from custOrder in context.Orders
                where custOrder.Customer.CustomerId == someCustomerId
                select custOrder)).LoadIntoCacheAsync(options);
    task.Wait();
    var resultSet = task.Result.ToList();
}

FromCacheOnlyAsync

The following example fetches the customer information only from the cache if the Customer entity exists. If not, the result set returned will be empty, as the database is ignored in this call.

using (var context = new NorthwindContext())
{
    var options = new CachingOptions
    {
        StoreAs = StoreAs.SeperateEntities
    };

    var task = (from cust in context.Customers
                where cust.CustomerId == someCustomerId
                select cust).FromCacheOnlyAsync();
    task.Wait();
    var resultSet = task.Result.ToList();
}

See Also

Caching Options for EF Core Caching
Cache Handle from EF Core Context
Query Deferred APIs for EF Core Caching
Logging Entity Framework Core Caching

Back to top Copyright © 2017 Alachisoft