Equality Operator (==) and Value Types in C#

Udemy

Background

This article is in the continuation of series of articles regarding how Equality works in .Net, the purpose is to have the developers more clear understanding on how .Net handles equality for different types. We have already seen equality for primitive types, reference types works, we also discussed separately how equality works differently for String type. Following are some points which we were able to understand until now.

Key Points Learned So Far

  • By default the virtual Object.Equals method does reference equality for reference types and value equality for value types, but for value types it uses reflection which is a performance overhead for value types and any type can override Object.Equals method to change the logic of how it checks for equality e.g. String, Delegate and Tuple do this for providing value equality, even though these are reference types.
  • Object class also provides a static Equals method which can be used when there is chance that one or both of the parameters can be null, other than that it behaves identical to the virtual Object.Equals method.
  • There is also a static ReferenceEquals method which provides a guaranteed way to check for reference equality.
  • IEquatable<T> interface can be implemented on a type to provide a strongly typed Equals method which also avoids boxing for value types. It is implemented for  primitive numeric types but unfortunately Microsoft has not been very proactive  implementing for other value types in the FCL( Framework Class Library ).
  • For Value Types using == operator gives us the same result as calling Object.Equals but underlying mechanism of == operator is different in IL( Intermediate Language ) as compared to Object.Equals, so the Object.Equals implementation provided for that primitive type is not called, instead an IL instruction ceq gets called which says that compare the two values that are being loaded on the stack right now and perform equality comparison using CPU registers.
  • For Reference Types, == operator and Object.Equals method call both work differently behind the scenes which can be verified by inspecting the IL code generated. It also uses ceq instruction which do the comparison of memory addresses.
 If the above points does not makes sense to you, it would be better to read it from the start, following are the links to the previous content related to it:

 Equality Operator for Value Types 

We have already learned that what the Equality operator does for both the primitive types and reference types. One case that we haven’t tested yet is that what happens for the non-primitive value types. This time we will be focusing on the value types.

We will be using the same example that we used before, so we will declare a Person type as struct and we will compare two instances to see if they are equal not using Object.Equals method which we did previously and we know that it does the value comparison which is very in-efficient as for value types it uses reflection to iterate through the fields and check for equality of each one, but instead we will compare two Person type objects using the  == operator.

The Person type definition looks like:

public struct Person
{
    private string _name;
 
    public string Name
    {
        get
        {
            return _name;
        }
    }
 
    public Person(string name)
    {
        _name = name;
    }
 
    public override string ToString()
    {
        return _name;
    }
}


If we write the following code in Main and build the project, what will we see:

class Program
    {
 
        static void Main(String[] args)
        {
 
            Person p1 = new Person("Ehsan Sajjad");
            Person p2 = new Person("Ehsan Sajjad");

      Console.WriteLine(p1.Equals(p2));
            Console.WriteLine(p1 == p2);

            
            Console.ReadKey();
 
        }
 
    }

When we try to build the above program, the first line where we are comparing p1 and p2 using Equals method will have no problem, but the build fails on line 2 where we are using == operator with the following error message:

Operator ‘==’ cannot be applied to operands of type `Person` and `Person`
 So the above makes one thing clear to us that the Equality operator does nothing for the non-primitive value types, for using the equality operator for non-primitive value types we need to provide an operator overload for the type.

Let’s modify the above example to add the equality operator overload for the Person struct, we will be now specifying what the == operator should do for two Person objects being compared, following is the syntax to provide the overload for == operator if we want to provide the implementation so that what the operator should do when used for two objects of type Person:

public static bool operator ==(Person p1, Person p2)
{
      
}

After adding the above code in the Person struct we would be able to compile the code written in Main method of Program, but note that this would not compile still as the overload has return type bool as per signatures but we are returning nothing, this is just to give idea how to write == operator overloaded implementation for a user defined Value Type.

We saw in one of the previous posts that String overloads the equality operator to make sure that it does the same thing as Equals method, so whenever you are defining a new type make sure that it does the same thing with both the method and the operator, if we provide either of them it is generally a good thing to do. Following is an example code that will help us understand why it is a good practice:

class Program
{

    static void Main(string[] args)
    {


        Tuple tuple1 = Tuple.Create(1, 2);
        Tuple tuple2 = Tuple.Create(1, 2);

        Console.WriteLine(ReferenceEquals(tuple1, tuple2));
        Console.WriteLine(tuple1.Equals(tuple2));
        Console.WriteLine(tuple1 == tuple2);

        Console.Read();

    }


As you can see we are instantiating two tuples containing same values i.e. 1 and 2, Tuple is a generic class which comes within Framework Class Libraries provided by Microsoft which simply provides a way to group couple of values together in a single object. The Tuple.Create(1, 2); is a nicer way to instantiate a new tuple saving developer to explicitly write the generic types in the code.

Now we are comparing the tuples to see if they are equal or not, Tuple is a reference type, so we are checking equality using ReferenceEquals check to confirm that we are dealing with two separate instances, next we are comparing if they are equal using the Equals method, and lastly we are comparing using equality operator aka == operator, Let’s run this program and following is the output of the above program:


For some of you the result might be a surprise, we can see that ReferenceEquals has returned false which means that both are different instances, but the == operator and Equals method have returned the opposite result, the == operator says that both are not equal while the Equals method is saying that they are equal.

What’s actually happening above is that Tuple overrides the Equals method in a way that it checks for value equality for the objects. Microsoft figured that when you are dealing with a type whose purpose is just to encapsulate couple of fields that is probably what you want equality to mean, so as the two Tuple instances have the same value the Equals method says that they are equal, but Microsoft didn’t provided the overload for == operator and that means that == operator has just done what it is meant to be doing and will always do for reference type that does not provide an overload and checks reference equality and has returned False in this case as both are different instances.

I am pretty sure that has confused you, of course the behavior is confusing and it did confuse me as well when I was digging in to it. Almost no one is going to expect this kind of behavior and it is strongly recommended to not add this kind of behavior is any type we define.

If you override the Equality then it is much better to provide the == operator overload to make sure that method and the operator always gives the same result and if you implement the IEquatable<T> interface then you should do same for that as well.


Comparison of == Operator and Object.Equals Method

Finally let’s quickly see how the == operator and Equals method differ as far as their behavior is concerned:

  • For Primitive Types e.g. int, float, long, bool etc both the == operator and Object.Equals method will compare the values i.e. 1 is equal to but 1, but 1 is not equal to 0 
  • For most of the Reference Types both the == operator and Object.Equals method will by default compare the references, you can modify this behavior by overloading the == operator or overriding the Object.Equals method but if you want the behavior of both to be consistent and don’t want to surprise other developers and yourself you must do the both (overload == operator and override the Equals method).
  • For Non-primitive Value Types the Object.Equals method will do the value equality using Refection which is slow and this is overridden behavior of course, but the equality operator is by default not available for value types unless you overload the == operator for that type which we saw in the example above.
  • There is also another minor difference that for reference types the virtual Equals method cannot work if the first parameter is null but that is trivial, as a workaround the static Equals method can be used which takes both the objects to be compared as parameter 

Summary

So after all the above points and discussion we can conclude that a lot of the time the operator and the method gives the same result in practice, but since the syntax of the operator is so much convenient that developers most of the time prefer the operator. In the next post we will be discussing what are the situations where == operator might not be the preferable but instead Equals method would be preferable.



Story of Equality in .Net - Part 6

Udemy

Background:

This article is in the continuation of series of articles regarding how Equality works in .Net, the purpose is to have the developers more clear understanding on how .Net handles equality for different types.

What we learned so far:

Following are the key points that we learned from the previous parts until now:
  • C# does not syntactically distinguish between value and reference equality which means it can sometimes be difficult to predict what the equality operator will do in particular situations.
  • There are often multiple different ways of legitimately comparing values. .Net addresses this by allowing types to specify their preferred natural way to compare for equality, also providing a mechanism to write equality comparers that allow you to place a default equality for each type 
  • It is not recommended to test floating point values for equality because rounding errors can make this unreliable
  • There is an inherent conflict between implementing equality, type-safety and good Object Oriented practices.
  • Net provides the types equality implementation out of the box, few methods are defined by the .Net framework on the Object class which are available for all types.
  • By default the virtual Object.Equals method does reference equality for reference types and value equality for value types, but for value types it uses reflection which is a performance overhead for value types and any type can override Object.Equals method to change the logic of how it checks for equality e.g. String, Delegate and Tuple do this for providing value equality, even though these are reference types.
  • Object class also provides a static Equals method which can be used when there is chance that one or both of the parameters can be null, other than that it behaves identical to the virtual Object.Equals method.
  • There is also a static ReferenceEquals method which provides a guaranteed way to check for reference equality.
  • IEquatable<T> interface can be implemented on a type to provide a strongly typed Equals method which also avoids boxing for value types. It is implemented for  primitive numeric types but unfortunately Microsoft has not been very proactive  implementing for other value types in the FCL( Framework Class Library ).
  • For Value Types using == operator gives us the same result as calling Object.Equals but underlying mechanism of == operator is different in IL( Intermediate Language ) as compared to Object.Equals, so the Object.Equals implementation provided for that primitive type is not called, instead an IL instruction ceq gets called which says that compare the two values that are being loaded on the stack right now and perform equality comparison using CPU registers.
  • For Reference Types== operator and Object.Equals method call both work differently behind the scenes which can be verified by inspecting the IL code generated. It also uses ceq instruction which do the comparison of memory addresses.
If you want to read the other parts published until now, you can read them here:
We will be looking at String type in this post that how Equality works for it. You might be aware that for strings the equality operator compares values not references which we had seen in the first post of this series. It is because String has overridden the implementation of Equals to behave in this manner.
We will investigate how == operator and Object.Equals method behave for equality checking.

Equality Operator and String:

Consider the following piece of code:

class Program
{
 
    static void Main(String[] args)
    {
 
        string s1 =  "Ehsan Sajjad";
        string s2 = String.Copy(s1);
 
        Console.WriteLine(ReferenceEquals(s1, s2));
        Console.WriteLine(s1 == s2);
        Console.WriteLine(s1.Equals(s2));
            
        Console.ReadKey();
 
    }
 
}

The above code is very similar to what we have looked at before as well, but this time we have String type variables in place. We are creating a string and holding its reference in s1 variable and on next line we are creating copy of the string and holding its reference in another variable names s2.

Then we are checking for reference equality for both the variables that are they both pointing to same memory location or not, then in next two lines we are checking the output of equality operator and Object.Equals method.

Now we will build the project and run it to see what it outputs on the console. The following is the output printed on console:


You can see that ReferenceEquals has returned false which means that both the string are different instances, but the == operator and Equals method have returned true, so it is clear that for Strings the equality operator does indeed test the value for equality not the reference exactly as Object.Equals does.

Behind the Scenes of Equality Operator for String

Let’s see how the equality operator is doing that. Now let’s examine the IL code generated for this example. For doing that, Open the Visual studio Developer Command Prompt, for opening it, go to Start Menu >> All Programs >> Microsoft Visual Studio >> Visual Studio Tools>> Developer Command Prompt


Type ildasm on the command prompt, this will launch the IL disassembler which is used  to look at the IL code contained in an assembly, it is installed automatically when you install Visual Studio, so you don’t need to do anything for installing it.


Click the File Menu to open the menu, and click the Open Menu Item which will bring up the window to browse the executable that we want to disassemble.


Now navigate to the location where your application executable file is located and open it.


This will bring up the code of the assembly in hierarchical form, as we have multiple classes written in the assembly, so it has listed down all the classes.

Now the code which we want to explore is in the Main Method of the Program class so navigate to the Main method and double click it to bring the IL code for it.


The IL code for main looks like this:


IL for String override of Equals Method

First let;s look at the IL generated for s1.Equals(s2), and there are no surprises as it is calling Equals method but this time it is calling the method implementation of IEquatable<string> which takes a string as argument, not the Object.Equals override is being called, because the compiler found a better match for the string argument that was supplied. See the picture below:


IL for == operator for String

Now let’s examine what is the IL generated for the string equality checking done using equality operator, so we can see the now there is no ceq instruction being called which we saw in previous posts that for value types and reference types that instruction is executed when we check for equality using == operator, but for String we have call to a new method named op_equality(string, string) which takes two string arguments, we have not seen this kind of method before, so what it is actually? 

The answer is it is the overload of C# equality operator (==) which is provided by String class. In C# when we define a type, we have the option to overload the equality operator for that type, for  example , for Person class which we have been seeing in previous examples will look like following, if we overload the == operator for it:

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
 
    public static bool operator == (Person p1, Person p2)
    {
        bool areEqual = false;
        if (p1 == null || p2 == null)
            areEqual = false;
        if(p1 == null  && p2 == null )
            areEqual = true; 
        if (p1.Id == p2.Id)
            areEqual = true;
        else
            areEqual =  false;
 
        return areEqual;
    }
}


So the above code is pretty simple, We have declared an operator overload which would be a static method, but the thing to notice here is that the name of the method is operator == The similarity of declaring operator overload with static method is not a con-incidence, actually it is compiled as a static method by the compiler, because we know and had been discussed before that IL (Intermediate Language) has no concept of operators, events etc , it only understands fields and methods, so operator overload can only exist as a method which we observed in IL code above, the overload operator code is turned by compiler in to a special static method called op_Equality().

First it is checking if any of the passed instances is null then they are not equal, then we see if both are null then obviously both references are equal so it will return true, and next it checks if Id property of both references is equal then they are equal, otherwise they are not equal.

This way we can define our own implementation for our custom types according to the business requirements. As we discussed earlier that equality of two objects is totally dependent on the business flow of the application, so two objects might look equal to someone but not equal to some other according to their business logic.

This makes one thing clear that Microsoft has provided == operator overload for String class, and we can even see that if we peek in to the source code of String class in Visual Studio by using Go to Definition, which would be like:



In the above snapshot, we can see that there are two operator overload one for equality and the other is inequality operator which works exactly the same way but the negation of equality operator output.

Summary


  • We have now enough understanding of what C# Equality operator does in the case of Reference Types. Following the thing that we need to keep in mind:
    • If there is an overload for the equality operator for the type being compare, it uses that operator as a static method.
    • If there is no overload of operator for reference type, the equality operator compares the memory addresses using ceq instruction.
  • One thing to note is that Microsoft made sure that == operator overload and Object.Equals override always give the same result even though they are in fact different methods. So that is an important thing we need to keep in mind when we start implementing our own Equals override, we should also take care of the equality operator as well, otherwise our type will end up giving different result using Equals override and equality operator which would be problematic for consumers of the type. We will be seeing in another post how we can override Equals method in a proper way.
  • If we are changing how Equality works for a type, we need to make sure we provide implementation for both Equals override and == operator overload so that they both give the same result, and that’s obvious otherwise it would be confusing for other developers who will be using our implemented type .






Story of Equality in .Net - Part 5

Udemy

Background:

This article is in the continuation of series of articles regarding how Equality works in .Net, the purpose is to have the developers more clear understanding on how .Net handles equality for different types. You may want to read the previous post as well:


In the previous post (i.e. Part 4) we compared the result of equality comparison of value type using == operator and Object.Equals method and the result was same but the mechanism for evaluating the equality is different as the IL generated for Object.Equals and == operator was different, which means that == operator does not call Object.Equals behind the scenes but it uses CPU’s registers to determine if the two value type variable are equal or not.

Introduction:

I hope that after reading the previous posts, you have now better understanding how the c# equality operator works for primitive types like int, float, double etc. In this post we will be focusing on how the c# equality operator and Equals method behave for reference types either they are framework class library types or user defined custom types. If you haven’t read previous parts and interested in reading from start about this topic, you can navigate all parts published before here:


== Operator and Reference Types 

If you recall from the previous post we saw an example using reference types for equality that it checks for reference equality, now we will modify the same example to see that equality operator compiles to what in case of reference types.

class Program
{
 
    static void Main(String[] args)
    {
        Person p1 = new Person();
        p1.Name = "Ehsan Sajjad";
 
        Person p2 = new Person();
        p2.Name = "Ehsan Sajjad";
        
        Console.WriteLine(p1.Equals(p2));
        Console.WriteLine(p1 == p2);
        Console.ReadKey();
    }     
 
}


Now we will test using these both method of checking equality i.e. equality operator of c# and Equals method of Object type. If we runt his example we will see false  printed on the console two times which was expected result as Person is a reference type and those are two different instances of person with difference memory reference.

From the output we can easily deduce that both the equality operator and Equals method check for reference equality for reference types and that’s actually what’s happening.  So, Equality operator also checks reference equality not value equality for reference types just same like Equals method.

What Happens Behind the Scenes?

Now let’s examine the IL code generated for this example. For doing that, Open the Visual studio command prompt, for opening it, go to Start Menu >> All Programs >> Microsoft Visual Studio >> Visual Studio Tools>> Developer Command Prompt


Type ildasm on the command prompt, this will launch the ildasm which is used  to look at the IL code contained in an assembly, it is installed automatically when you install Visual Studio, so you don’t need to do anything for installing it.


Browse the folder where your executable is and open it using File Menu. This will bring up the IL code of your executable.

The IL code for the above C# code looks like:


If we see the IL code for p1.Equals(p2), there are no surprises, it is comparing the equality by calling the virtual Equals method of Object, and the method signatures are pretty clear, as they say it requires an object, so this is actually a virtual call to Object.Equals method, this is the best type’s method match that C# compiler picked.

Now if we look at IL code generated for equality operator comparison of the objects. It is exactly the same instruction used which we saw for the integer example in the previous part. It is not calling any method to do the comparison, it is just loading both arguments to the evaluation stack and doing a ceq, which is a dedicated IL instruction to check for equality probably using the CPU’s hardware.

You might be thinking how does that achieve the reference equality?  We know that Person is a class which is a reference type which means whatever the variable of type Person contains is the address in memory of where the Person object is on managed heap.

Both arguments p1 and p2 are holding the memory addresses and you know addresses in memory are just numbers which means that they can be compared using the ceq statement for equality just like the integers you declare in the code. In fact this ceq is comparing the addresses to see if they are equal, in other words whether the reference is pointing to the same memory address is reference equality.

Summary

  • We saw that == operator and Object.Equals method call both work differently behind the scenes which we can verify by inspecting the IL code generated.
  • We saw that for Reference types as well using == operator gives us the same result as calling Object.Equals but underlying mechanism of == operator is different in IL as compare to Object.Equals, which is that it does not uses the Object.Equals instead it uses ceq instruction which do the  comparison of memory addresses using hardware instructions .




Grid View with Server Side Filtering, Sorting and Paging in asp.net mvc 5

Udemy

 

Download Source Code


Background

In the previous post, we talked about how we can achieve a gridview type functionality in asp.net mvc same like we have in asp.net webforms. We saw that how easy it is to implement a gird using jQuery datatables plugin which provides vital features such as searching, sorting and pagination.


One thing to notice in the previous post is that all the features provided by the plugin are client side which means that all the data is loaded in the page first and then the plugin handles the data on client side for searching, pagination and sorting which is fine if the result sets coming are not very big, but it can cause problems if the table is too big or the data is not that much but grows gradually as applications is used, so if that is the case this way of creating the grid would fail in long run.

Introduction

In this post, we will be seeing how we can implement the server side pagination, searching and sorting which is of course a better approach in the long run or for the applications where datasets are too big.
We will be modifying the source code from the previous post for this, so let’s get started.

First of all, we need to install datatables.mvc5  from nuget package manager, it is a datatables model binder to controller implemented by Stefan Nuxoll. You may be thinking why we need this package, it is because the binder will provide strongly typed model posted at controller, which will help us to avoid reading the request parameter and will also save us from type-casting the parameters from Request as all the parameters posted in Request object are not type safe so we have to convert them manually to their destination type, which will help the developers to focus on business logic instead of playing around with Http parameters, checking them and casting to the right type.
 The good thing about this binder is that you can add custom parameters sent in the request if your business requirements need that.
 You can add your own custom parameters if needed by providing your own implementation of IDataTablesRequest, and you will also need to override the BindModel and MapAdditionalColumns method of it.

So now we will install datatables.mvc5 , Go to Tools >> NuGet Package Manager >> Manage Nuget Packages for Solution and click it.

The package manager will get opened and by default it will be displaying the installed nugget packages in your solution, click the Browse button and then search for datatable.mvc5 package, then select it and check the projects of the solution in which you want to install this package, in our case we are installing in it GridExampleMVC web project only as per requirement and then press the install button.



Select the correct package which is in the above screenshot the top one returned in the search results and install it.



If the installation of package goes successful, you will be able to see in the References of the project:



Go to the Index.cshtml file and update the html of the view by removing the thead and tbody elements of the table. Your updated html would be:

<div class="row">
    <div class="col-md-12">
        <div class="panel panel-primary list-panel" id="list-panel">
            <div class="panel-heading list-panel-heading">
                <h1 class="panel-title list-panel-title">Assets</h1>
            </div>
            <div class="panel-body">
                <table id="assets-data-table" class="table table-striped table-bordered" style="width:100%;">
                </table>
            </div>
        </div>
    </div>
</div>

We removed the head and body of table because it would get generated by the datatables plugin itself. Now we will have to update the jQuery datatables initialization so that it loads data from server side via ajaxing.

For that add the following code in the Index.cshtml view:

@section Scripts
{
    
<script type="text/javascript">
        var assetListVM;
        $(function () {
            assetListVM = {
                dt: null,

                init: function () {
                    dt = $('#assets-data-table').DataTable({
                        "serverSide": true,
                        "processing": true,
                        "ajax": {
                            "url": "@Url.Action("Get","Asset")"
                        },
                        "columns": [
                            { "title": "Bar Code", "data": "BarCode", "searchable": true },
                            { "title": "Manufacturer", "data": "Manufacturer", "searchable": true },
                            { "title": "Model", "data": "ModelNumber", "searchable": true },
                            { "title": "Building", "data": "Building", "searchable": true },
                            { "title": "Room No", "data": "RoomNo" },
                            { "title": "Quantity", "data": "Quantity" }
                        ],
                        "lengthMenu": [[10, 25, 50, 100], [10, 25, 50, 100]],
                    });
                }
            }

            // initialize the datatables
            assetListVM.init();

        });

</script>
    
 }

After this, we will write the Get action code in the AssetController, for that first we need to reference the System.Linq.Dynamic namespace as we will be using the methods provided for dynamic linq in our action, for that go to Nuget Package Manager once again and search for System.Linq.Dynamic package and install it in your project.



After installing the package, go to AssetController and write the Get action implementation which will be :

public ActionResult Get([ModelBinder(typeof(DataTablesBinder))] IDataTablesRequest requestModel)
{
    IQueryable<asset> query = DbContext.Assets;
    var totalCount = query.Count();

    #region Filtering
    // Apply filters for searching
    if (requestModel.Search.Value != string.Empty)
    {
        var value = requestModel.Search.Value.Trim();
        query = query.Where(p => p.Barcode.Contains(value) ||
                                 p.Manufacturer.Contains(value) ||
                                 p.ModelNumber.Contains(value) ||
                                 p.Building.Contains(value)
                           );
     }

     var filteredCount = query.Count();

     #endregion Filtering

     #region Sorting
     // Sorting
     var sortedColumns = requestModel.Columns.GetSortedColumns();
     var orderByString = String.Empty;

     foreach (var column in sortedColumns)
     {
        orderByString += orderByString != String.Empty ? "," : "";
        orderByString += (column.Data) + (column.SortDirection == Column.OrderDirection.Ascendant ? " asc" : " desc");
     }

     query = query.OrderBy(orderByString == string.Empty ? "BarCode asc" : orderByString);

     #endregion Sorting

     // Paging
     query = query.Skip(requestModel.Start).Take(requestModel.Length);


     var data = query.Select(asset => new
     {
        AssetID = asset.AssetID,
        BarCode = asset.Barcode,
        Manufacturer = asset.Manufacturer,
        ModelNumber = asset.ModelNumber,
        Building = asset.Building,
        RoomNo = asset.RoomNo,
        Quantity = asset.Quantity
     }).ToList();

     return Json(new DataTablesResponse(requestModel.Draw, data, filteredCount, totalCount), JsonRequestBehavior.AllowGet);
}


Now build the project, and run it in browse to see the working grid view with server side filtering, paging and sorting in action.



Beginners Guide for Creating GridView in asp.net mvc 5

Udemy

Download Source Code


Introduction

In this post, we will be seeing how we can create a grid view in asp.net mvc, same like we have in asp.net web form. There are many their party both server side and also client side plugins written in jQuery are available which provide all the essential functionalities that we have in web forms which include searching, sorting and paging etc. It totally depends on the requirements of specific application if the search is needed client side or server side, same for the other functions.

You can download the source code from this link.

Libraries Available

Some of the libraries and plugins available are:
·         Grid.Mvc
·         MVCGrid.NET
·         PagedList.MVC
·         JQuery.Grid
·         JQuery Grid for ASP.NET MVC
·         JQuery DataTables

Using Jquery DataTables

All have their pros and cons, but personally I have found jQuery datatables to be a good choice. It is highly flexible. It supports pagination, instant-search, multi-column ordering. It also supports almost all the data sources to which it can be binded, some of which are:
·         DOM
·         JavaScript
·         Ajax
·         Server-side processing

One of the best option which I like in it is that it supports both client side searching, pagination, sorting etc, but it also provides option to have server side processing of it, as there can be case where we have too much data in database and in that case client side paging wouldn’t be a good option, just think millions of rows in a table and if they are binded to it using client side pagination, it will make or page unresponsive due to high amount of rows processing and html rendering.

We will first see an example of how we can implement it using client side processing. So, let’s get started. We will have a working grid with searching, sorting and paging at the end of the post which will look like:


First of all create database and table that we will be using in this post, Open SQL Management Studio and run the following script:

CREATE DATABASE [GridExampleMVC]  
 GO  
   
 CREATE TABLE [dbo].[Assets] (  
     [AssetID]                   UNIQUEIDENTIFIER NOT NULL,  
     [Barcode]                   NVARCHAR (MAX)   NULL,  
     [SerialNumber]              NVARCHAR (MAX)   NULL,  
     [FacilitySite]              NVARCHAR (MAX)   NULL,  
     [PMGuide]                   NVARCHAR (MAX)   NULL,  
     [AstID]                     NVARCHAR (MAX)   NOT NULL,  
     [ChildAsset]                NVARCHAR (MAX)   NULL,  
     [GeneralAssetDescription]   NVARCHAR (MAX)   NULL,  
     [SecondaryAssetDescription] NVARCHAR (MAX)   NULL,  
     [Quantity]                  INT              NOT NULL,  
     [Manufacturer]              NVARCHAR (MAX)   NULL,  
     [ModelNumber]               NVARCHAR (MAX)   NULL,  
     [Building]                  NVARCHAR (MAX)   NULL,  
     [Floor]                     NVARCHAR (MAX)   NULL,  
     [Corridor]                  NVARCHAR (MAX)   NULL,  
     [RoomNo]                    NVARCHAR (MAX)   NULL,  
     [MERNo]                     NVARCHAR (MAX)   NULL,  
     [EquipSystem]               NVARCHAR (MAX)   NULL,  
     [Comments]                  NVARCHAR (MAX)   NULL,  
     [Issued]                    BIT              NOT NULL,  
     CONSTRAINT [PK_dbo.Assets] PRIMARY KEY CLUSTERED ([AssetID] ASC)  
 )  
 GO

There is complete sql script file attached in the source code, so you can use it to create the database and table with sample data.

Now, create a new asp.net mvc 5 web application. Open Visual Studio 2015. Go to File >> New >> Project



From the dialog navigate to Web and select ASP.Net Web Application project and click OK.


From Templates, Select MVC, check the unit tests if you will write unit tests as well for your implementations and click OK.
Our project is created with basic things in place for us. Now we will start by creating the database context class as we will be using Entity Framework for the Data Access.

First of all we need to create model for the Asset table which we will be using for retrieving data using ORM.
In Model folder, create a new class named Asset:

using System.ComponentModel.DataAnnotations;

namespace GridExampleMVC.Models
{
    public class Asset
    {
        public System.Guid AssetID { get; set; }

        [Display(Name = "Barcode")]
        public string Barcode { get; set; }

        [Display(Name = "Serial-Number")]
        public string SerialNumber { get; set; }

        [Display(Name = "Facility-Site")]
        public string FacilitySite { get; set; }

        [Display(Name = "PM-Guide-ID")]
        public string PMGuide { get; set; }

        [Required]
        [Display(Name = "Asset-ID")]
        public string AstID { get; set; }

        [Display(Name = "Child-Asset")]
        public string ChildAsset { get; set; }

        [Display(Name = "General-Asset-Description")]
        public string GeneralAssetDescription { get; set; }

        [Display(Name = "Secondary-Asset-Description")]
        public string SecondaryAssetDescription { get; set; }
        public int Quantity { get; set; }

        [Display(Name = "Manufacturer")]
        public string Manufacturer { get; set; }

        [Display(Name = "Model-Number")]
        public string ModelNumber { get; set; }

        [Display(Name = "Main-Location (Building)")]
        public string Building { get; set; }

        [Display(Name = "Sub-Location 1 (Floor)")]
        public string Floor { get; set; }

        [Display(Name = "Sub-Location 2 (Corridor)")]
        public string Corridor { get; set; }

        [Display(Name = "Sub-Location 3 (Room No)")]
        public string RoomNo { get; set; }

        [Display(Name = "Sub-Location 4 (MER#)")]
        public string MERNo { get; set; }

        [Display(Name = "Sub-Location 5 (Equip/System)")]
        public string EquipSystem { get; set; }

        public string Comments { get; set; }

        public bool Issued { get; set; }

    }
}


Now Navigate to Models folder from Solution Explorer and open IdenityModels.cs file , we will add a property for the Asset table in the database context, which will be the Entity Framework representation of Asset table which we created using the script. Add new property in the ApplicationDbContext class:

public class ApplicationDbContext : IdentityDbContext
{
    public ApplicationDbContext()
        : base("DefaultConnection", throwIfV1Schema: false)
    {
    }

    public DbSet Assets { get; set; }

    public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }
}


The above is the default entity framework settings for asp.net identity 2.0, we are extending it with our own tables for which we have added new DbSet for Asset table.

Now add an empty controller in Controllers folder named AssetController, which we will be using for all the Asset related work. Here is how it should look like:


public class AssetController : Controller
    {
        // GET: Asset
        public ActionResult Index()
        {
            return View();
        }
    }


Now we will install jQuery datatables that we will be using to build the gird, Go to Tools >> NuGet Package Manager >> Manage Nuget Packages for Solution and click it.


The package manager will get opened and by default it will be displaying the installed nugget packages in your solution, click the browser button and then search for jQuery datatables package, then select it and check the projects of the solution in which you want to install this package, in our case we are installing in it GridExampleMVC web project only as per requirement and then press the Install button.






Visual Studio will prompt to tell that it is going to modify the solution, you will have to press ok to continue the installation of the package.

After the nugget package is installed successfully, we need to include the necessary js and css of jquery datatables in the view where we will use it, for that we have to register the jquery datatables, for that open the BundleConfig.cs file locate in App_Start folder and add the following code for css and js files at the end:

bundles.Add(new ScriptBundle("~/bundles/datatables").Include(
                        "~/Scripts/DataTables/jquery.dataTables.min.js",
                        "~/Scripts/DataTables/dataTables.bootstrap.js"));

bundles.Add(new StyleBundle("~/Content/datatables").Include(
          "~/Content/DataTables/css/dataTables.bootstrap.css"));


After registering the scripts and css for datatables, we need to add them in our master layout which is by default _Layout.cshtml located in Views >> Shared which is defined in the _ViewStart.cshtml located in the same location.






Before writing the controller code, we need to configure the connection string for entity framework that will be used to connect database when it will be doing database operations i.e. running queries. So our connection string should be pointing to a valid data source so that our application won’t break when we run it.


For that open web.config and provide the connection string for the database. In config file you will find the under configuaration node connectionStrings, you will need to modify the connection string in that node according to your system. In my case it looks like:

<connectionstrings>
    <add connectionstring="Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=GridExampleMVC;Integrated Security=True;MultipleActiveResultSets=true" name="DefaultConnection" providername="System.Data.SqlClient"/>
</connectionstrings>

Now in controller add a property for database context that we will be using for querying the database.

private ApplicationDbContext _dbContext;

public ApplicationDbContext DbContext
{
    get
    {
        return _dbContext ?? HttpContext.GetOwinContext().Get();
    }
    private set
    {
        _dbContext = value;
    }

}

This property we will be using to query the database with entity framework in all actions of the controller wherever needed.

Now in the index action, we will simply fetch all the rows of the table and pass it to view:

public ActionResult Index()
{
    return View(DbContext.Assets.ToList());
}


Our complete controller class code now looks like:

using GridExampleMVC.Models;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Microsoft.AspNet.Identity.Owin;


namespace GridExampleMVC.Controllers
{
    public class AssetController : Controller
    {

        private ApplicationDbContext _dbContext;

        public ApplicationDbContext DbContext
        {
            get
            {
                return _dbContext ?? HttpContext.GetOwinContext().Get();
            }
            private set
            {
                _dbContext = value;
            }

        }

        public AssetController()
        {

        }

        public AssetController(ApplicationDbContext dbContext)
        {
            _dbContext = dbContext;
        }

        // GET: Asset
        public ActionResult Index()
        {
            return View(DbContext.Assets.ToList());
        }
    }
}

Here comes the view part now, where we will write code about how it should render as html. So create a view with Template Empty (Without Model) for the Index action and add the following code in it:

@model IEnumerable< GridExampleMVC.Models.Asset>

<div class="row">
    <div class="col-md-12">
        <div class="panel panel-primary list-panel" id="list-panel">
            <div class="panel-heading list-panel-heading">
                <h1 class="panel-title list-panel-title">Assets</h1>
            </div>
            <div class="panel-body">
                <table id="assets-data-table" class="table table-striped table-bordered" style="width:100%">
                    <thead>
                        <tr>
                            <th>Bar Code</th>
                            <th>Manufacturer</th>
                            <th>Model Number</th>
                            <th>Building</th>
                            <th>Room No</th>
                            <th>Quantity</th>
                        </tr>
                    </thead>
                    <tbody>
                        @foreach (var asset in Model)
                        {
                            <tr>
                                <td>@asset.Barcode</td>
                                <td>@asset.Manufacturer</td>
                                <td>@asset.ModelNumber</td>
                                <td>@asset.Building</td>
                                <td>@asset.RoomNo</td>
                                <td>@asset.Quantity</td>
                            </tr>
                        }
                    </tbody>
                </table>
            </div>
        </div>
    </div>
</div>

@section Scripts
{
    
 <script type="text/javascript">
     $(document).ready(function () {

         $('#assets-data-table').DataTable();
     });
    </script>   
    
 }

Now run the application and you will see a grid with sorting, searching and filtering available in it, but there is one problem in it, which is it is processed on client side, all the data is rendered by view when action is called which may make page performance slow or increases page load time if there are a large number of rows coming.

We will be seeing in another post how we can make it more better by using server side paging, sorting and filtering which is surely a better approach where we have huge data set.