How To Handle Database and Buss.Logic in MVC 3 If the Requirements Change?


Let's think of a scenario if my requirements change and I want to make some changes to the application code logic and database as well. It would be a lengthy and hectic tasks to go and manually change line by line in buss.logic. So let's a look how can perform very light weighted operations with high in performance using DropCreateDatabaseIfModelChanges<>base class, which serves better in mentioned scenario.

Let's specify some class named "Student Class" in models folder has the Following Properties:

Student.cs
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;

namespace MVC_Basic_Application.Models
{
    public class Student
    {
        [Key]
        public int StudentId { getset; }

        [Required(ErrorMessage = "Please Enter FirstName")]
        [StringLength(10, ErrorMessage = "FirstName morethan 10 charcs")]
        public string FirstName { getset; }

        [Required(ErrorMessage = "Please Enter LastName")]
        [StringLength(10, ErrorMessage = "LastName morethan 10 charcs")]
        public string LastName { getset; }

        [Range(5, 50, ErrorMessage = "Age Should Be Between 5 and 50")]
        public int Age { getset; }

        [Required(ErrorMessage = "Please Enter Location")]
        [StringLength(10, ErrorMessage = "Location morethan 10 charcs")]
        public string Location { getset; }

    }

And My DataContext Class in models folder: StudentStateEntities.cs is Specified

StudentStateEntities.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;

namespace MVC_Basic_Application.Models
{
    public class StudentStateEntities:DbContext
    {
        public DbSet<Student> Students { getset; }
    }
}

And Now I will get chance to analyse what to do when My requirement changes and how to handle my application logic and database simultaneously. The Answer arises to this question which helps to another model class name "StudentStateIntializer" where we inherit from base class DropCreateDatabaseIfModelChanges<> , This Class help to drop and recreate the database if the requirement changes as per the application basis with necessary properties specified in Student class.

So the Fully Completed StudentStateIntializer.cs looks like this:

StudentStateIntializer.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;

namespace MVC_Basic_Application.Models
{
    public class StudentStateIntializer:DropCreateDatabaseIfModelChanges<StudentStateEntities>
    {
        protected override void Seed(StudentStateEntities context)
        {
            var stu = new List<Student>
            {
                new Student
                {
                    StudentId=1,
                    FirstName="Vijay",
                    LastName="Prativadi",
                    Location="Banglore",
                    Age=25

                },
                 new Student
                {
                    StudentId=2,
                    FirstName="Uday",
                    LastName="Prativadi",
                    Location="Mumbai",
                    Age=28
                }
            };
            stu.ForEach(p=>context.Students.Add(p));
        }
    }
}

Before you render changes to the webbroswer just go to global.asax.cs

Add this line in Application_Start() of global.asax.cs file:

Database.SetInitializer<StudentStateEntities>(new StudentStateIntializer());

The Completed Code of global.asax.cs looks like this:

Global.asax.cs

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Data.Entity;
using MVC_Basic_Application.Models;

namespace MVC_Basic_Application
{
    // Note: For instructions on enabling IIS6 or IIS7 classic mode,
    // visit http://go.microsoft.com/?LinkId=9394801

    public class MvcApplication : System.Web.HttpApplication
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new HandleErrorAttribute());
        }

        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                "Default"// Route name
                "{controller}/{action}/{id}"// URL with parameters
                new { controller = "Student", action = "Index", id = UrlParameter.Optional } // Parameter defaults
            );

        }

        protected void Application_Start()
        {
            Database.SetInitializer<StudentStateEntities>(new StudentStateIntializer());

            AreaRegistration.RegisterAllAreas();

            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);
        }
    }
}

So Now Everything should work Fine. So, lets do rebuild and take a look at output which looks like this:

  out1 (2).jpg
But think like, All of sudden my requirement is changed and I want to add an other property where it should be affecting in my database and all other parts of my  application logic whereby rendering towards my output.

Let's See how to Handle this case

Let's Add New Property Named : "Email"

public string Email { getset; }

The Completed Student.cs looks like this:

Student.cs with New Email Property

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;

namespace MVC_Basic_Application.Models
{
    public class Student
    {
        [Key]
        public int StudentId { getset; }

        [Required(ErrorMessage = "Please Enter FirstName")]
        [StringLength(10, ErrorMessage = "FirstName morethan 10 charcs")]
        public string FirstName { getset; }

        [Required(ErrorMessage = "Please Enter LastName")]
        [StringLength(10, ErrorMessage = "LastName morethan 10 charcs")]
        public string LastName { getset; }

        [Range(5, 50, ErrorMessage = "Age Should Be Between 5 and 50")]
        public int Age { getset; }

        [Required(ErrorMessage = "Please Enter Location")]
        [StringLength(10, ErrorMessage = "Location morethan 10 charcs")]
        public string Location { getset; }

        [Required(ErrorMessage = "Email is required")]
        [RegularExpression(@"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}" +
                           @"\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\" +
                           @".)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$",
                           ErrorMessage = "Email appears to be invalid.")]
        public string Email { getset; }
    }

Simultaneously, we make necessary changes in StudentStateIntializer.cs as well

StudentStateIntializer.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;

namespace MVC_Basic_Application.Models
{
    public class StudentStateIntializer:DropCreateDatabaseIfModelChanges<StudentStateEntities>
    {
        protected override void Seed(StudentStateEntities context)
        {
            var stu = new List<Student>
            {
                new Student
                {
                    StudentId=1,
                    FirstName="Vijay",
                    LastName="Prativadi",
                    Location="Banglore",
                    Age=25,
                    Email="vijayprativadi@hotmail.com"

                },
                 new Student
                {
                    StudentId=2,
                    FirstName="Uday",
                    LastName="Prativadi",
                    Location="Mumbai",
                    Age=28,
                    Email="uday@gmail.com"
                }
            };
            stu.ForEach(d=>context.Students.Add(d));
        }
    }
}

The Controller Should Accept Student.cs as Model Class and StudentStateEntities.cs as DataContext Class Which Looks like this:
 

  out2 (1).jpg

So When you rebuild and run the application you will find the new field added to your output and database aswell.

The output looks like this: 

out3 (1).jpg
The Changes Made to database with DropCreateDatabaseIfModelChanges<> base class will look this(Design Mode):

  Output4.jpg

 I hope this article is useful to you.