Sie sind auf Seite 1von 10

07/08/2018 jQuery DataTables Interaction with Server Side Caching - CodeProject

jQuery DataTables Interaction with Server Side


Caching
Proneetkumar Pradeep Ray, 7 Aug 2018

Boost/Optimize your Jquery DataTable and perform Server side pagination, Global Search, Column wise Search) using Server Side
Caching

Download source - 762.1 KB

Introduction
While you are engage with comprehensive data and trying to attach in jQuery Datable or any other jQuery based data table/grid,
most of cases it will slow down and ultimately you will face performance issue.

Here, I have listed few of cases, you might be find challenges in optimization on render data table. Suppose you need to display
more than millions of records along with multiple columns using as mentioned following:

Linq/Lambda Expression for complex query along with multiple tables.


Time Consuming Business Logic or Complex Query in Store Procedure.

We have to perform server side chunk processing of data. I mean to say, We need to handle pagination, ordering of data on specific
column (Ascending/Descending Order) as well you need to search text from multiple column and sometime on specific/individual
column.

Whenever you face, out of controls to optimizing on data source whether data comes from Linq/Lambda expression using Entity
Framework or Sql Store Procedure.

Or

If there is heavy traffic on your sql server database then it is advisable to store final data source into Caching In Memory.

To keep in caching memory, your final data source or model object after executed complex query then you can easily handle all kind
of server-side process on your grid or table E.g. Server side pagination, Global Search as well multi column search.

Concept/Logic to boost DataTables grids


We know very well, once the data has come to IIS Server or In Memory, we can easily handle server side process.

1. Global Search (Search Text in all column from entity)


2. Individual Column Search (Search Text in specific column)
3. Order By (Ordering on specific column Ascending or Descending Order)
4. Page Size (Loading N numbers of rows in each page change request. Here we need to supply Page Row Index and N-
numbers of records to display)

I have separated following module to execute my concept:

Cach Engine Manager (Utility Class/helper Class) - It is core module of this concept. Its main job is to store in memory of retrieved
data from Entity framework or Ado.net Sql operations. I have used some specific key to maintain save or retrieve object from Cache
Engine. I have used multiple function here

Add() - For Adding Object to Cache Memory using specific key. Same key will essential to Clear object from
Cache Engine, Check(Exist) availability of object from Caching as well Get from Caching.

https://www.codeproject.com/Articles/1250812/jQuery-DataTables-Interaction-with-Server-Side-Ca?display=Print 1/10
07/08/2018 jQuery DataTables Interaction with Server Side Caching - CodeProject

Clear() - To Release Cache Memory using specific key

Exists() - Check availability of object in Cache using specific key

Get() - To retrieve object from Cached using specific key

Model or Context Preparation- In this section I am trying to create model and mapped with database. I have tried to interaction
with sql database using Code First Approach. I have taken very simple entity sample E.g.CountryData, StateData, CityData. We
can store as much as possible records to store in sql server to check performance.

Server Side - Ajax post request payload from Jquery DataTable - Here we are going to write a code for Side operation which is
requested from Jquery DataTabes. I have used two major methods

A. QuickResponse(DTParameters param) : This action methods initially will helps to get object availablity from caching. If
there is not available from Cache Engine then it perform sql server interaction/database operation to retreive data then after
it will store to Cache Engine.

So next onward every request it will not lookup or perform sql database query. It save lots of time to serve each and every
request from client side(Jquery DataTable E.g. Pagination, Gloabal Search, Individual Column Search, Sorting). There are
many benefit to use this caching integration approach. So every request from client (jquery Datatable) server will not
execute sql database operation. Suppose there is N-number is client is using same datatable then all client will serve quickly
with same cached object/retrieve from server using Cache Engine. These are the main benefits to use such caching
approach. It reduces traffic or load from Sql Server.

but there are also disadvantaging to use this approach, if somebody has performed some sql operate e.g Insert Record,
Update Record or Delete Record. So this data table will go out of dated or record will display old data because it is coming
from Caching memory. It takes time to initialization. E.g. Retrieve data from Sql Server and then save to caching. Every
stored object in Caching has limited life span. Cache will automatically clean after passes this time span. You can control life
span of store cache memory as per our requirements.

Such scenario, We need to put some button on grid E.g. Refresh button. Its main job is to clear the cache container. Once
clear the container from Cache Memory it automatically again load fresh copy of data from sql server. Finally, we need some
separate method to clear memory from Cache Engine. Here I have written function for same job named
as RefreshContainer()

It will better to show some where last modified or cached store time. So end user comes to know last
update on cached engine. If he/she needs to up to date information from server, need to click Refresh
Container button from Server.
B. RefreshContainer() : This function main job is to clear object from cached memory using some specific key.

Client Side - Html Page/Razor Page contains with Jquery DataTable- If you are familiar to initiliaze jquery datatable then it is
very easy to understand. I have juest keep all setting and information in JqDTConfig E.g. All Columns, Ajax Url, Buttons. It is
important to know I have taken one more value LastModifiedOn on each ajax request. This value is helful to display last updated
cached container.

ReloadCacheEngine() : This function is going to execute while end user want to clear cache container from server. It is
simple ajax request which is going to call RefreshContainer()

Now, I have started to write code with self-explanation along with comment summary. Hope this module can help one level up to
boost your comprehensive jquery datatable.

Cache Engine Manager Integration


Fetched data source or final out come from complex query, need to utilize Cache Utility to store data.

/// <summary>
/// Cache Engine Utility Manager. This utility is helpful to store data in sytem memory.
/// </summary>
public class CacheManager
{
static int CacheExpiryTime =
Convert.ToInt32(ConfigurationManager.AppSettings["CacheTimeOut"]);
/// <summary>
/// Adding data or model to store System
/// </summary>
/// <param name="key">Need to set some key with while storing data to system. This key
will help to retrieve same information</param>
/// <param name="o">Data or Model</param>
public void Add(string key, object o)
{
HttpRuntime.Cache.Insert(key, o, null,
DateTime.Now.AddMinutes(CacheExpiryTime),//in minutes
https://www.codeproject.com/Articles/1250812/jQuery-DataTables-Interaction-with-Server-Side-Ca?display=Print 2/10
07/08/2018 jQuery DataTables Interaction with Server Side Caching - CodeProject
System.Web.Caching.Cache.NoSlidingExpiration);
}
/// <summary>
/// Clear or release data from system
/// </summary>
/// <param name="key"></param>
public void Clear(string key)
{
HttpRuntime.Cache.Remove(key);
}
/// <summary>
/// Check Model/Data is already stored or not in system
/// </summary>
/// <param name="key">Your pre defined key while storing data or model to
system</param>
/// <returns></returns>
public bool Exists(string key)
{
return HttpRuntime.Cache[key] != null;
}
/// <summary>
/// Fetching/retrieve data from Cached Memory. Note it return type is object that's why
you need to deserialize it before use.
/// </summary>
/// <param name="key">Your pre defined key while storing data or model to
system</param>
/// <returns>Model or data as object data type</returns>
public object Get(string key)
{
try
{
return HttpRuntime.Cache[key];
}
catch
{
return null;
}
}
}

Model and Context Preparation


public class CountryData
{
//Taking long data type (instead of int) for strong large number of recods
public long Id { get; set; }
public string Country { get; set; }
}
public class StateData
{
public long Id { get; set; }
public string State { get; set; }
//Set ForeignKey as CountryId
public long CountryId { get; set; }
[ForeignKey("CountryId")]
public virtual CountryData CountryData { get; set; }
}
public class CityData
{
public long Id { get; set; }
public string City { get; set; }

//Set ForeignKey as StateId


public long StateId { get; set; }
[ForeignKey("StateId")]
public virtual StateData StateData { get; set; }
}

//Context preparation

https://www.codeproject.com/Articles/1250812/jQuery-DataTables-Interaction-with-Server-Side-Ca?display=Print 3/10
07/08/2018 jQuery DataTables Interaction with Server Side Caching - CodeProject
public class EntityContext : DbContext
{
public EntityContext() : base("name=CacheManager") { }
public DbSet<CountryData> ScientistData { get; set; }
public DbSet<StateData> StateData { get; set; }
public DbSet<CityData> CityData { get; set; }
}

Set connection string with catalog "CacheManager" which is mentioned in Context construction

Execute command for code first approach as following :

1. Enable-Migrations
2. Add-Migration IntialCreate
3. Update-Database

https://www.codeproject.com/Articles/1250812/jQuery-DataTables-Interaction-with-Server-Side-Ca?display=Print 4/10
07/08/2018 jQuery DataTables Interaction with Server Side Caching - CodeProject

Server Side - Ajax post request payload from Jquery


DataTable
Jquery DataTable will call to server and trying get data. There are many kind of operation need to perform here.

E.g. Handle Server Side Pagination, Global Search, Column wise search etc.

[HttpPost]
public ActionResult QuickResponse(DTParameters param)
{
int count;
string LastUpdateOn;
var CityData = new List<CityResult>();
var CacheManager = new CacheManager();
//Check in Cache Storage availablity of data or model object
if (CacheManager.Exists(CityCacheKey))
{
CityData = (List<CityResult>)CacheManager.Get(CityCacheKey);
https://www.codeproject.com/Articles/1250812/jQuery-DataTables-Interaction-with-Server-Side-Ca?display=Print 5/10
07/08/2018 jQuery DataTables Interaction with Server Side Caching - CodeProject
LastUpdateOn = (string)CacheManager.Get(LastUpdateOnCacheKey);
}
else
{
CityData = new QueryHelper().LoadCity();
LastUpdateOn = DateTime.Now.ToString("dd-MMM-yyyy HH:mm:ss");
//Storing data or model in Cache Storage
CacheManager.Add(CityCacheKey, CityData);
CacheManager.Add(LastUpdateOnCacheKey, LastUpdateOn);
}
//Taken DataTable Container...
IEnumerable<CityResult> DataTableContainer = CityData;
string SearchText = param.Search != null ? param.Search.Value : string.Empty;
//Global Search (Search in all columns).
if (!string.IsNullOrEmpty(SearchText))
DataTableContainer = GlobalSearchInCityData(DataTableContainer,
SearchText.Trim().ToLower());

//Individual Column Search (Search Text in Specific Column)


DataTableContainer = MultiColumnSearch(param, DataTableContainer);
if (!(string.IsNullOrEmpty(param.SortOrder) &&
string.IsNullOrEmpty(param.Order[0].Dir.ToString())))
DataTableContainer = SortList(DataTableContainer, param.SortOrder,
param.Order[0].Dir.ToString());

//Set Total Record in Database/Cache Engine


count = DataTableContainer.Count();
CityData = DataTableContainer.ToPaged(param.Start, param.Length).ToList();
DTResult<CityData> result = new DTResult<CityData>
{
draw = param.Draw,
data = CityData,
recordsFiltered = count,
recordsTotal = count,
LastModifiedOn = LastUpdateOn
};
var JsonResult = Json(result, "application/json", JsonRequestBehavior.AllowGet);
JsonResult.MaxJsonLength = int.MaxValue;
return JsonResult;
}
//Searching in all columns
private IEnumerable<CityResult> GlobalSearchInCityData(IEnumerable<CityResult>
Container, string SearchText)
{
Container = Container.Where(u =>
(u.City != null && u.City.ToLower().Contains(SearchText)) ||
(u.State != null && u.State.ToLower().Contains(SearchText)) ||
(u.Country != null && u.Country.ToLower().Contains(SearchText)));
return Container;
}
//Sorting for City Records....
private IEnumerable<CityResult> SortList(IEnumerable<CityResult> Container, string
sortColumn, string sortColumnDir)
{
return Container.OrderBy(sortColumn + " " + sortColumnDir); ;
}
//Column wise Searching....
private IEnumerable<CityResult> MultiColumnSearch(DTParameters Param,
IEnumerable<CityResult> Container)
{
string SearchText = Param.Search != null ? Param.Search.Value : string.Empty;
//Essential for Multi Column Search
Param.Columns.Where(w => w.Search != null &&
!string.IsNullOrEmpty(w.Search.Value)).ToList().ForEach(f =>
{
var SearchKey = HttpUtility.UrlDecode(f.Search.Value.Trim().ToLower());
if (f.Data == "City")
{
Container = Container.Where(w => w.City != null &&
w.City.ToLower().Contains(SearchKey));
}
else if (f.Data == "State")
{
Container = Container.Where(w => w.State != null &&

https://www.codeproject.com/Articles/1250812/jQuery-DataTables-Interaction-with-Server-Side-Ca?display=Print 6/10
07/08/2018 jQuery DataTables Interaction with Server Side Caching - CodeProject
w.State.ToLower().Contains(SearchKey));
}
else if (f.Data == "Country")
{
Container = Container.Where(w => w.Country != null &&
w.Country.ToLower().Contains(SearchKey));
}
});
return Container;
}
/// <summary>
/// Clear or release data from Cache memory. Data can not be available longer.
/// </summary>
/// <returns></returns>
public ActionResult RefreshContainer()
{
try
{
new CacheManager().Clear(CityCacheKey);
return Json(new { status = true }, JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
return Json(new { status = false, message = ex.ToString() },
JsonRequestBehavior.AllowGet);
}
}
}

/// <summary>
/// Handle Pagination on model or data object
/// </summary>
public static class EntityExtension
{
public static IEnumerable<T> ToPaged<T>(this IEnumerable<T> table, int start = 0, int
length = 0)
{
if (length > 0)
return table.Skip(start).Take(length).ToList();
else return table.Skip(start);
}
}

Client Side - Html Page/Razor Page contains with Jquery DataTable

<link href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css " rel="stylesheet"


/>
<link href="https://cdn.datatables.net/buttons/1.5.1/css/buttons.dataTables.min.css"
rel="stylesheet" />
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/buttons/1.5.1/js/dataTables.buttons.min.js"></script>
<script type="text/javascript">
//To Refresh Cache Container
var ReloadCacheEngine = function () {
$.ajax({
url: "/Cached/RefreshContainer", success: function (response) {
if (response.status == true) {
alert("Cache Engine has successfully updated!");
location.reload();
}
else
bootbox.alert(response.message);
}
});
}
//Jquery DataTable Object.It has Ajax,Columns and Button details
var JqDTConfig = {
Ajax: {
"url": '/Cached/QuickResponse/',

https://www.codeproject.com/Articles/1250812/jQuery-DataTables-Interaction-with-Server-Side-Ca?display=Print 7/10
07/08/2018 jQuery DataTables Interaction with Server Side Caching - CodeProject
"type": "Post",
"datatype": "json",
dataFilter: function (response) {
var JsonResponse = JSON.parse(response);
$("#LastUpdatedOn").attr("title", "Click to refresh the Cach Engine. Last
Updated on " + JsonResponse.LastModifiedOn);
return response;
},
},
columns: [
{ "data": "City" },
{ "data": "State" },
{ "data": "Country" }
],
buttons: [
{
text: "<i id='LastUpdatedOn' aria-hidden='true' style='color:green'><img
height='15 px' src='/Content/refreshIcon.png'/></i>",
action: function (e, dt, node, config) {
ReloadCacheEngine();
}
}]
};
$(function () {
//Jquery DataTable Initilization
var table = $('#example').DataTable({
"lengthMenu": [[10, 20, 50, 100, 250, 500], [10, 20, 50, 100, 250, 500]],
"oLanguage": {
"sLengthMenu": "_MENU_ &nbsp;"
},
"order": [[0, "desc"]],
"processing": true,
"serverSide": true,
dom: 'Bfrtip',
dom: 'lBfrtip',
buttons: JqDTConfig.buttons,
"searchHighlight": true,
"ajax": JqDTConfig.Ajax,
"columns": JqDTConfig.columns
});
$('#example tfoot th').each(function () {
var title = $(this).text().trim();
$(this).html('<input type="text" style="width:100%;" title="' + title + '"
placeholder="' + title + '" />');
})
//INIT EVENTS
table.columns().every(function () {
$('input', this.footer()).on('keyup change', function () {
table.column($(this).parent().index() + ':visible')
.search(this.value)
.draw();
});
});

});
</script>
<h2>Server Side Caching with Pagination - Jquery DataTable</h2>
<table class="table" id="example">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.City)
</th>
<th>
@Html.DisplayNameFor(model => model.State)
</th>
<th>
@Html.DisplayNameFor(model => model.Country)
</th>
</tr>
</thead>
<tfoot>
<tr>
<th>

https://www.codeproject.com/Articles/1250812/jQuery-DataTables-Interaction-with-Server-Side-Ca?display=Print 8/10
07/08/2018 jQuery DataTables Interaction with Server Side Caching - CodeProject
@Html.DisplayNameFor(model => model.City)
</th>
<th>
@Html.DisplayNameFor(model => model.State)
</th>
<th>
@Html.DisplayNameFor(model => model.Country)
</th>
</tr>
</tfoot>
</table>

Result/Out Put

https://www.codeproject.com/Articles/1250812/jQuery-DataTables-Interaction-with-Server-Side-Ca?display=Print 9/10
07/08/2018 jQuery DataTables Interaction with Server Side Caching - CodeProject

Points of Interest
Most of cases not required to display live records, such scenario we can store fetched data or final outcome into Caching
memory.
I have taken 5 Minutes of Caching memory life span for demonstration purpose. You can set accordingly as per project's
need. Even you can get fresh copy or live fresh record by click on refresh button from grid.
Cutomize DTParameters (JQuery Datatable posting model) added feild as LastModifiedOn for updated time details. It will
update timings of grid each and every request E.g. Pagination or Searching text.
This mechanism can boost your compressive jQuery DataTable and Reduce load or traffic on your ms sql datatbase server

License
This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author


Proneetkumar Pradeep Ray
Team Leader Nebula Infraspace LLP
India

Having 6+ year experience on Microsoft .Net/Programming

Object oriented programming


.Net Framework Architecture
Console Programming / Dynamic or Runtime Program Execution
Multi Threaded Programming
Windows Application Programming
RegEx
TCP/IP Communication
Http Protocol and REST API Architecture
Socket Programing
SMS, Email, Domain Registration API Integration
PayPal, Authorize.Net Payment Gateway
EntityFramework, Linq & Lamda Expression
JavaScript, Ajax and Jquery
Asp.net Web Applications
MVC Razor View Engine Framework
NopCommerce Customization, InfusionSoft Integration
Azure Web App, Salesforce and Amazon Web Services
Azure Media Services
Media Player Integration and Encryption on Streaming Framegments
Microsoft Sql Server Database

Comments and Discussions


2 messages have been posted for this article Visit https://www.codeproject.com/Articles/1250812/jQuery-DataTables-
Interaction-with-Server-Side-Ca to post and view comments on this article, or click here to get a print view with messages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile Article Copyright 2018 by Proneetkumar Pradeep Ray
Web01-2016 | 2.8.180807.1 | Last Updated 7 Aug 2018 Everything else Copyright © CodeProject, 1999-2018

https://www.codeproject.com/Articles/1250812/jQuery-DataTables-Interaction-with-Server-Side-Ca?display=Print 10/10

Das könnte Ihnen auch gefallen