Get Started with Caching in Entity Framework (EF) Core using NCache

What is NCache?

NCache is an Open Source in-memory distributed cache for .NET, Java, and Node.js. NCache is extremely fast and linearly scalable and caches application data to reduce expensive database trips. Use NCache to remove performance bottlenecks related to your data storage and databases and scale your .NET, Java, and Node.js applications to extreme transaction processing (XTP).

What is EF Core?

The ADO.NET Entity Framework is a popular object-relational mapping framework. It provides abstraction from underlying relational data that is stored in a database and presents its conceptual schema to the application, preventing the need to write database persistence code.

Entity Framework Core is a lightweight and open source and cross platform framework to handle the high transaction applications where scalability and performance cannot be compromised. However, in such critical cases, the database quickly becomes a bottleneck as the database tier does not support adding on more servers. To achieve this scalability and reliability NCache provides extension methods for Entity Framework Core.

EFCore can serve as an object-relation mapper which eliminate the need of most of the data-access code, and it has been widely used to handle the high transactions .NET server applications (ASP.NET, Web Services, Microservices, and other server apps). Most of the time the application faces the scalability bottlenecks from database when there is high load from the network which can be easily eliminated by using the distributed caching inside EF Core. This blog will explain you how to integrate the NCache into EF Core.

Why NCache?

As our application transaction load grows, we are able to accommodate request loads by linearly scaling the application tier with more application servers. However, we cannot add more database servers to handle the increased load. This is where a distributed cache such as NCache comes into picture. You can cache the frequently accessed data to improve response times. The distributed nature of caching in NCache for Entity Framework Core ensures optimal performance under extreme transaction loads by making the cache linearly scalable too.

Integrating the NCache with EFCore is very simple. In this blog I’m going to explain how the NCache will work with EF Core using three extension methods.

  1. FromCache()
  2. GetCache()
  3. LoadIntoCache()
  4. FromCacheOnly()

NCache provides the distributed caching which works with multi-server environments by giving a high data reliability and 100% uptime without comprising the performance of the cache. Caching in Entity Framework Core with NCache fills the gaps of performance and scalability and makes it highly efficient. You can observe the performance improved when the transaction load grows during the high traffic period.

Install NCache Manager:

Download NCache from NCache Download Center (alachisoft.com). I highly recommend you to install the Enterprises edition so that you can explore all the features. Before the installation make sure .NET 6 has been installed in your machine

After completing the Download and installation process, you can run the NChace Web Manger in the bowser from localhost 8251 port, as shown in the below figure.

NCache Web Manager

We can create a clustered and Local Caches from the NCache Manager application.

For this demo I have created a local cache and named it as “myLocalCache” using Ncache Manager as shown in the below figure.

Click here to check how to create a local Cache using NCahce Web Manager.

NCache web Manager

NCache with EFCore:

I’m going to use the same .NET Core application which was created in my previous article on Clean Architecture.

You can get a complete source code in GitHub.

We have a different layer in this Project. Go to HotelBook.Persistance which is our data access layer with EF Core.

Install EntityFrameworkCore.NCache package from NuGet Package Manager in HotelBooking.Persistance Project.

Let’s configure the NCache into our EFCore project.

Open PersistenceServiceRegistration.cs file and add below code in AddPersistance service collection method.

            string cacheId = configuration.GetSection("NCacheConfig").GetSection("CacheId").Value.ToString();          
            NCacheConfiguration.Configure(cacheId, DependencyType.SqlServer);

Set your Cache ID in appSetting.jsom file as a Key value pair.

"NCacheConfig": {
    "CacheId": "myLocalCache" //Replace "demoCache" with the name of your cache
  }

myLocalCache is my localCache Name/Id

NCacheConfiguration class is use to initialize the Ncache configuration with Configure method by passing the CacheId and dependency type. In our case the dependency type is SQLServer

Let’s start with FromCache() extension method.

FromCache()

We have Get All Hotel list API in our application. Assume when user log in to the application the landing page will list all the hotels’ details, so this will be one of our frequently used API in our application. So, by caching this dataset will drastically reduce the load to the database.

FromCahce() extension method first it will check for the query result the cache, if it doesn’t exist it will fetch it from the database and added to the cache. The result response time will be faster in future request.

We can store the query result as either separate entities or a single collection. In this case saving the result set in the cache as a collection will be more sensible, because any change in the result set will be completely updated from the database.

After executing the query, you can check the connection details from the Local cache statistics. 

Client Connection

From the statistic it’s quite obvious that one connection has been established.

public List<Hotel> ListAllHotels()
        {
            var options = new CachingOptions
            {
                // To store as collection in cache
                StoreAs = StoreAs.Collection
            };
var resultSet = (from cust in _dbContext.Hotels
                             select cust).FromCache(options);
return resultSet.ToList();
}

During first call, it will fetch the data from the database and save it in cache. From Future call the data will be returned from cache, it will not hit the database.

LoadIntoCache()

We can make the cache into our primary and reliable datasource for our reference data by using LoadIntoCache() extension method. This method will load entire reference data into cache by querying the database. You cannot always expect the correct results from your queries against the cache because there will be some scenario where your data might be in the database whereas the query is only searching the cache.

public List<Hotel> ListAllHotels()
        {
            var options = new CachingOptions
            {
                // To store as collection in cache
                StoreAs = StoreAs.SeperateEntities
            };
          
            var resultSet = (from cust in _dbContext.Hotels

                             select cust).LoadIntoCache(options);

            return resultSet.ToList();
        }

In caching option, we have defined to Store it as separate entities which makes each Hotel store as a separate entity and make it available for all kinds of query combination and also faster retrieval of a single hotel detail.

LoadIntoCache fetch the LINQ query result set from the database and loads the data into a cache. Whenever this method execute it will fetch the data from the database, which means it will always talk with database.

FromCacheOnly():

To use FromCacheOnly() you must load the entire reference data in the cache. FromCacheOnly() extension method will always search in cache and return the result set, it will never reach to the database. So, it’s very important we should query only the reference data from the cache when we use the FromCacheOnly, which means the reference data which is stored in the data with LoadIntoCache() can only be queried using FromCacheOnly() to get a reliable result set.

       public List<Hotel> ListAllHotels()
        
            {
            var options = new CachingOptions
            {
                // To store as collection in cache
                StoreAs = StoreAs.SeperateEntities
            };


            //FromCacheOnly

            var resultSet = (from cust in _dbContext.Hotels
                             where cust.Name == "jack68815" ||cust.Name== "jack23939"
                             select cust).FromCacheOnly();

            return resultSet.ToList();

        }

From the above code FromCacheOnly() will not reach the database to query and return the result set instead it will query the reference data in the cache. It doesn’t talk with database.

GetCache():

EF Core context allows the user to add and update the entities in the database. So, it’s important whenever there is a change in the context the cache context also should be updated. NCache provides a cache handle to perform add, update and remove operation directly on the cache.

Let’s add new hotel in the EFCore, the SaveChanges() method will be used to save any changes in the database context and by calling GetCache() and call Insert().

var options = new CachingOptions
            {
                QueryIdentifier="HotelEntity",
                Priority = Alachisoft.NCache.Runtime.CacheItemPriority.Default
            };
            var hotel = new Hotel { HotelId =new Guid(), Name="Gowtham"};
            
            _dbContext.Hotels.Add(hotel);
            _dbContext.SaveChanges();

            Cache cache = _dbContext.GetCache(); //get NCache instance
            cache.Insert(hotel, out string cacheKey, options);

From the above code the new hotel data has been inserted in the database. Get the cache context using GetCache() and call Insert() to Insert the record into a cache context.

Summary:

We saw what is NCahce, how to work with NCache with distributed cache mechanism and then a NCache Entity framework extension methods used to cache the EF Queries and how effective it could be by caching the EF queries and handling the reference data by reducing the load to the database.

Download the source code here

gowthamk91

Leave a Reply

%d bloggers like this: