Thursday, December 26, 2013

Step By Step How to create a Data Repository with Data Caching in ASP.NET MVC 4

         By Carmel Schvartzman

In this tutorial we'll learn how to create a Data Repository with Data Caching in ASP.NET MVC 4. The MVC C# code for this step-by-step tutorial is available for download on GitHub at :
https://github.com/CarmelSoftware/Data-Repository-with-Data-Caching-in-ASP.NET-MVC-4
Its GitHub Wiki page is:
https://github.com/CarmelSoftware/Data-Repository-with-Data-Caching-in-ASP.NET-MVC-4/wiki

The Data Repository is a class which is designed to implement the Repository Pattern. This software pattern was created in order to access, cache in memory and persist in the database the application data. That means, the Repository will fetch the data ONLY IF IT'S NOT AVAILABLE IN MEMORY. 
There are, however, Repository implementations with no use of caching. The caching only stands to avoid unnecesary round trips to the SQL server. But when scalability of the sites is on the stage, may be we don't want to choke our web server's memory. Then, caching is not only redundant, but also dangerous as a waste of the web server resources. Of course using the Cache or the Application storages is less wasteful than using the Session ASP.NET storage, but even then the RAM memory of the web server should be taken into account and preserved as much as possible.
In this tutorial we'll add a Repository functionality with caching support to a new ASP.NET MVC 4 app.
Let's say we have an MVC internet application with an Entity Data Model mapped to an SQL server database. This EDM maps just two entities: Blog and Comment:

Our Repository will be added to the Model folder, which holds all the bussiness logic of the MVC application. Therefore focus the Model folder and create a new class: MyDataRepository.

Next, we'll create our Data Context, using the class created by the Entity Framework, inheriting DbContext: this class will be located under the Entity Data Model .edmx node: just open it until you see the XXX.Context.cs file:

 open it to see the name of your data context class which inherits from DbContext:

 This is your Data context and you'll add it to the Repository:

 Also add a null check to be sure your DbContext is there:

 Enclose the properties in a region:

 Take a look at the DbContext: you'll see that the Blog and Comment entities are represented by generic collections with a type DbSet<> :


 DbSet class provides the CRUD (Create Retrieve Update Delete) functionality we'll need to persist data changes to the database:


 The first method we'll add to our Repository will be the Save method. We separate this functionality so then we could make several changes all together and, just when done, we'll call the Repository Save method:



Now is time of designing the caching mechanism to store in memory the data. We'll use the caching infraestructure from the System.Runtime.Caching library, therefore add the pertinent reference:



Now focusing on the Model folder, create a new class named MyCachingProvider:



The class will use the ObjectCache, so add a private property to provide it. Implement the Get function instantiating the MemoryCache:



The first method we'll implement in our caching facility will be the Add functionality,and we'll take advantage of a MemoryCache aspect which puts this kind of storage far before from another storages like Application or Session: the caching policy. Later we'll state a caching expiration of a whole hour:




Now add the Remove functionality:



Also append the IsInMemory(key) method to check whether the required data is in memory:


Finally code the FetchData() method to get the data stored in memory:




 Next, we'll add all CRUD functionality to our Repository, as follows:



Notice that every C_UD (Create Update Delete) operation evicts the Comments from the Cache: that is because when a Comment is updated, created or deleted, the cached list remains in a async state with the actual data persisted in the database. We can either use the Sql Cache Dependencies functionality of the framework, or just evict the data from cache every time it is changed. For simplicity, we'll choose this later option.

 Finally, add the Retrieve functionality also for ALL the Comments and for just ONE selected Comment:


In the code you'll notice the use of the Caching functionality: first we check whether the data is in memory: if so we use the cache; elsewhere we fetch the data from the database and refresh the cache.


The RetrieveComment(id) method makes use of the previous RetrieveComment() method to get the List<> from memory:



 Now, let's check how our Repository works. On the server view, check the Comments table:


 Open the table contents, and clear them:




 Now, create a Testing class to run tests against the Repository. Inside the class, instantiate the Repository and create a new Comment:


 Next, call the Repository's AddComment() method, and Save() it all:


 Finally, in the HomeController make a call to our Test class:

 Build and debug the MVC application:



 As you can see, the original Comment has been instantiated.

 When finished the run, refresh the Comments table:



 The new record has been persisted by the Repository to the database.
Do it all again, adding the Retrieve part of the testing, fetching two comments to verify that the SECOND time we try to get data, it is loaded from the cache and not from database:


We get the Comment with CommentID = 2, as required:


Finally, test the Update method of the Repository, adding the code to change the Comment data:




Set a breakpoint inside the RetrieveComment() method to see how the "IF" clause causes to fetch data from the cache instead of from the database:





We've seen how to create a Data Repository with Data Caching in ASP.NET MVC 4 with support for all CRUD operations.
That's all!! 

Happy programming.....


כתב: כרמל שוורצמן