Friday, 30 August 2013

Understanding and using code first migration in asp.net mvc

Before object relational models (ORMs) came into existence, to create even a very simple web application that can store and retrieve data in the database was very hectic and a grueling experience.  This was because you have to first manually create the database and its tables, create the table relationships, then write the stored procedures or sql queries that will used to query the database before thinking about writing the business logic for the application.

But then ORMs started to appear around 2008 or there about, when many developers started to hunger for a better data provider to utilise in their applications, not that it totally eliminated all those process that is involved in working with the database, but it greatly reduced the drudgery involved in this process. So today we are going to look at the process involved in the creation of the backend database and see how easy it has become to accomplish it without leaving the comfort of your application.

Creating an mvc application and adding entity framework.

Now for brevity we are going to imagine that we want to create an application that will be used to add products with different categories in the database. We are going to build an asp.net mvc application using Visual Studio 2012. So without much ado lets fire off.

First create a new mvc 4 project using, name it anything you feel like but we are going to call ours "UsingCodeFirst" select internet template so that we can reduce the length of this article and concentrate on our topic without deviating. Next we are going to get the latest version of the entity framework dlls that we will be using in this application. To make it easy for us we are going use Package Manager Console in Visual Studio to get the entity framework. To use package manager console,  go to Tools, select Library Package Manager and then choose package manager console, when you have selected it, it will pop up as shown below.

To install the package type the following in the console and click enter and wait for the package manager console to install the required package and dependencies

PM> Install-Package EntityFramework -Version 5.0.0


Adding models to the application.



Next, its time to move on our merry way. Create 2 new poco classes in the models folder name it Product and Category respectively. Add the required properties as shown below


 public class Category
    {
 
        public Category()
        {
            this.Products = new List<Product>();
        }
 
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int CategoryID { getset; }
 
        [Display(Name = "Category name")]
        [StringLength(100)]
        [Required(ErroMessage = "Please enter the category name")]
        public string Name { getset; }
 
        [StringLength(500)]
        public string Description { getset; }
 
        //Concurrency checks
        public byte[] TimeStamp { getset; }
 
        //Navigational properties
        public virtual ICollection<Product> Products { getset; }
    }



public class Product
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int ProductID { getset; }
 
        [Required(ErroMessage = "Please enter the product name")]
        [Display(Name = "Product name")]
        [StringLength(100)]
        public string Name { getset; }
 
        [StringLength(500)]
        [Display(Name = "Product description")]
        public string Description { getset; }
 
        [Required(ErroMessage = "Enter the price of the product")]
        [Display(Name = "Product price")]
        public decimal Price { getset; }
 
        [ForeignKey("Category")]
        public int CategoryID { getset; }
 
        //Concurrency checks
        [Timestamp]
        public byte[] TimeStamp { getset; }
 
        //Navigational properties
        public virtual Category Category { getset; }
    }

You will notice that we used attributes a lot in our models, that is because we want to use Data Annotations to configure model and the database ( although you could use another form called fluent api ). In these models we simply configured a one to many relationship (ie: one category many products).

Next we will create a DataContext class, this is simply a class used by entity framework to map our models to the database. This class will also be used by our repositories to get and save products to the database. We shall call this class "Context" but you can call it anything.


public class Context : DbContext
    {
        public DbSet<Product> Products { getset; }
        public DbSet<Category> Categories { getset; }
    }


Now we will use the package manager console to enable migration for  our project. Code first migrations is what creates the database with its required tables and relationship using our data context and models. So on the package manager console, type "enable-migrations" to enable code first migrations, after that, type "add-migration nameOfMigrationToAdd" to create a new migration which will be added to the database when you update the database. Furthermore, type  "update-database" to update the newly created database with our migration. Mine added a class like this to the migration folder in the database.

 public partial class addedNewModels : DbMigration
    {
        public override void Up()
        {
            CreateTable(
                "dbo.Products",
                c => new
                    {
                    ProductID = c.Int(nullablefalseidentitytrue),
                    Name = c.String(nullablefalsemaxLength100),
                    Description = c.String(maxLength500),
                    Price = c.Decimal(nullablefalseprecision18scale2),
                        CategoryID = c.Int(nullablefalse),
                        TimeStamp = c.Binary(nullablefalsefixedLengthtruetimestamptruestoreType"rowversion"),
                    })
                .PrimaryKey(t => t.ProductID)
                .ForeignKey("dbo.Categories"t => t.CategoryIDcascadeDeletetrue)
                .Index(t => t.CategoryID);
            
            CreateTable(
                "dbo.Categories",
                c => new
                    {
                        CategoryID = c.Int(nullablefalseidentitytrue),
                        Name = c.String(nullablefalsemaxLength100),
                        Description = c.String(maxLength500),
                        TimeStamp = c.Binary(),
                    })
                .PrimaryKey(t => t.CategoryID);
            
        }
        
        public override void Down()
        {
            DropIndex("dbo.Products"new[] { "CategoryID" });
            DropForeignKey("dbo.Products""CategoryID""dbo.Categories");
            DropTable("dbo.Categories");
            DropTable("dbo.Products");
        }
    }

After that we will scaffold our models controller, so as not deviate from our current course. You can get the project from github.


This is the database diagram of our database in sql server management studio 2012

This brings us to the end of this topic. Hope you enjoyed it why not added a comment to let me know how you feel.












No comments:

Post a Comment