Nikolaos Kantzelis ASP.Net Blog

This blog will focus on ASP.NET Framework

Sponsors

About Me

Great Blogs

Creating a complete ASP.Net MVC 4.0 application with Visual Studio 2012, C# , EF 5.0 (Code First) - part 6

I have decided to write a series of posts on how to write a small ASP.Net MVC 4.0 application.I will develop this application step by step and I will explain everything that you need to know in order to develop ASP.Net MVC 4.0 applications. This is the sixth post in this series. You can find the first one here , the second one here , third one here , the fourth one here and the fifth one here. Make sure you read and understand those posts.

In this post I will add some validations to our application through Code First Data Annotations and migrate those changes to our database through EF Code First Migrations.

Right now there is no validation for the fields Rating and Comment of the MovieReview entity. I want to have a validation rule applied to the Rating field that will accept only values 1 to 10 and it will be mandatory. The Comment field will only be 100 characters long and also mandatory.We also want to have the characters for the Name property of the Movie entity  restricted to 70 and the name of the Director restricted to 50 characters.

Both of these properties should be mandatory.

I am going briefly to introduce Data Annotations and how to use them in our Code First Entity framework applications. I have developed my data access layer with EF. We have 3 development paradigms in EF. We have Database First,Model First and Code First. The last one (Code First) is the one I have used for this application and frankly speaking it is gaining in popularity amongst developers.

I will use another post also found in this blog to demonstrate Data Annotations.In order to fully understand what I am talking about, you need to read this post titled Using the Code First approach when building ASP.Net applications with Entity Framework . It will take some time to create this application but it is necessary in order to follow along.

With Data Annotations we can configure our domain-entity classes so that they can take best advantage of the EF. We can decorate our entity classes with declarative attributes.Let me give you an insight on how EF Code First works.EF Code First at run time, looks at the entity-domain classes and infers from them the in-memory data that it needs to interpret the queries and interact with the database.For example it assumes that any property named ID represents the key property of the class.Data Annotations "live" inside the System.ComponentModel.DataAnnotations. We do add Data Annotations to our domain classes declaratively using attributes. You can also do that imperatively using the Fluent API.

 

1) Launch Visual Studio and launch the ASP.Net MVC 4.0 application we have been developing so far.

2) Have a look at my entity class Movie

    public class Μovie
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Director { get; set; }
        public DateTime YearReleased { get; set; }
        public virtual ICollection<MovieReview> Reviews { get; set; }
    }

If I go to the entity above and make one little change renaming the

         public string Name { get; set; }

         to

         [Required, MaxLength(70)]
        public string Name { get; set; }

my application will get an error if compile and view it in a browser. It will compile but when I click on the Movie link on the menu I get the results shown in the following picture

 

 

3)

Make sure you add a reference to the System.ComponentModel.DataAnnotations namespace in the class file

using System.ComponentModel.DataAnnotations;

Both entities after applying the data annotation attributes follow:

public class Μovie
    {
       
         public int Id { get; set; }
        [Required, MaxLength(70)]
        public string Name { get; set; }
        [Required, MaxLength(50)]
        public string Director { get; set; }
        public DateTime YearReleased { get; set; }
        public virtual ICollection<MovieReview> Reviews { get; set; }
    }

 

  public class MovieReview
    {
       
         public int Id { get; set; }
        [Required,Range(1,10)]
        public int Rating { get; set; }
        [Required, MaxLength(50)]
        public string Comment { get; set; }
        public int MovieId { get; set; }
    }
}

 

There are other data annotation attributes like Key,ConcurrencyCheck,[Table("MyTable",Schema="guest")] but it is impossible to cover everything in this post.

Now I am compiling again my application and then when I click on the Movie link on the menu I get the results shown in the following picture


 

So we receive an error. Well, there is an explanation for that behavior. The Entity Framework always checks the model that is in effect, that we just configured against the model it used originally to create the database.

4) The Entity Framework detected that there is something different in this model. When we apply the Required attribute to an property in the entity then this field in the database should be not null.

In order to solve that problem we must apply Code First Migrations

Code First Migrations is an Entity Framework feature introduced in version 4.3 back in February of 2012.

Before the addition of Code First Migrations (4.1,4.2 versions), Code First database initialisation meant that Code First would create the database if it does not exist (the default behaviour - CreateDatabaseIfNotExists).

The other pattern we could use is DropCreateDatabaseIfModelChanges which means that Entity Framework, will drop the database if it realises that model has changes since the last time it created the database.

The final pattern is DropCreateDatabaseAlways which means that Code First will recreate the database every time one runs the application.

That is of course fine for the development database but totally unacceptable and catastrophic when you have a production database. We cannot lose our data because of the way that Code First works.

Migrations solve this problem.With migrations we can modify the database without completely dropping it.We can modify the database schema to reflect the changes to the model without losing data.

5) EF Code First Migrations is not activated by default. We have to activate them manually and configure them according to our needs.

We will open the Package Manager Console from the Tools menu within Visual Studio.Then we will activate the EF Code First Migration Features by writing the command “Enable-Migrations”.  

Have a look at the picture below.

 

This adds a new folder Migrations in our project. A new auto-generated class Configuration.cs is created.Another class is also created[CURRENTDATE]_InitialCreate.cs and added to our project.

The Configuration.cs  is shown in the picture below.

 

6) Now we need to update the database.

In the Configurations.cs I change the AutomaticMigrationsEnabled value to true

    public Configuration()
        {
            AutomaticMigrationsEnabled = true;

        }

Then in the Package Manager Console, we write the following

Update-Database -Verbose

This will fail because EF understands that we take a column that was nvarchar(max) and make it nvarchar(50) e.t.c

Then in the Package Manager Console, we write the following

Update-Database -Verbose -Force

This statement will succeed.

That will force the changes to the database.

Have a look at the picture below

 

As you can see all the changes were made to the database.

Now if we run again our application and test it (try to violate the 1-10 values allowed in the rating field) I will get the error shown in the picture below

 

I know we covered a lot in this post but you must understand it, if you want to master EF Code First.

Hope it helps!!!

 

Comments

Paulo said:

Keep these up! I'm working a huge application right now that uses a web server and multiple databases, and these tutorials are really helping! I would love it if you would go a bit more into detail about how to create more customazible databases and maybe even how to optimize database /reads and writes with other options like the method DropCreateDatabaseIfModelChanges

Thanks!

# January 17, 2013 3:21 PM

Fareed Nizami said:

Yes, that data was really helpful thaks Nik

# February 26, 2013 6:02 AM

wschke@yahoo.co.uk said:

I really enjoy looking at on this web site, it contains great content.

# April 1, 2013 11:08 AM