Data Annotations and Code First Migration in Entity Framework

This article explains data annotations and Code First migration in Entity Framework.

Introduction

Data Annotations are useful in the Entity Framework that we can apply to our model class and can enforce the validations further. It provides classes that will provide metadata for our Entity Framework DbSet.

Let’s continue from the previous article. If you already downloaded the code you can continue from it or click here to download.

Open the app_data folder and open the database (.mdf) file then drill down to the Artists table. If you check the datatype of the ArtistName column, it is a nvarchar(max) and "Allow Nulls" is checked.

datatype

We don’t intend to make the datatype size maximum but this is what the convention is that the Entity Framework uses. We said ArtistName is a string but we didn’t say how big it would be. So it is logical for the Entity Framework to make the ArtistName to be the maximum size. Here comes the data annotations as said in the introduction, it provides metadata for our Entity Framework dbSet.

To use DataAnnotations, we should refer to System.ComponentModel.DataAnnotations.

When it comes to numbers, the Entity Framework will map the SQL data types to .Net data types, for example, long becomes bigint.

The datetime is the trickiest one. Datetime is basically a value type, so it cannot be null, it should hold a value. Let us consider a scenario where we have productOrders. A ProductOrder will have an orderdate and a ship date. The Order date can be the requested date so we can have a value all the time, but what about ship date? There is a possibility of the ship date being null until the product is shipped to a destination. How to handle this? That is the use of the nullable<T> where t is a type variable and we have another option for this using Type keyword with a ? mark.

For example: Nullable<DateTime> shipDate; or else DateTime? shipDate both are acceptable.

Ok, let's go practical, open the code from the previous article and open the Artist.Cs in the model folder.

Decorate the ArtistName with the following two attributes:

  1. Required(): that specifies that the database field is a necessary column.

  2. String Length: that will use the maximum length as the first attribute and an optional minimum length.

The Artist.CS will look as in the following:

Artist

Also, as per the convention of the Entity Framework, we will make the property primary key if it is suffixed with ID or just ID. If we have a different property name then we can set it as the primary key using the [Key] Attribute.

The Entity Framework will make the class name the table name and also if we want to change this behavior with the new name then we can use the [Table(“newname”] attribute.

newname

Ok, now build it and run the application! Browse to Artist/Index.

You will get an Invalid Operation Exception. Well, it says that the DataContext has changed since the database was created and to consider the code migrations to update the database. We will look into it.

Exception

Updating the database if model changes

We must use the following procedure to enable the code first migrations.

  1. Open the package manager console (View -> Other Windows -> Package Manager Console).

  2. Type Enable-Migrations as in the following:

    Enable-Migrations

    It says more than one context type was found in the assembly CodeFirstDemo. Yes, one we created CodeFirstDemoContext, and another one is default UserContext for identity management and also it suggests how to update the one we created. Use the following command to enable the migrations:

    Enable-Migrations –ContextTypeName CodeFirstDemo.Models.CodeFirstDataContext – EnableAutomaticMigrations

    CodeFirstDemo

  3. We need to update the database so that changes will be executed to the database.

    If we wanted to say what changes will be updated, you can script that out using the Update-database script in the package manager console. When we execute this, we will get the error, Automatic Migrations are not enabled because it would result in data loss, this is because we will shrink the column ArtistName from the maximum size to 100. So the Entity Framework is thinking that there may be some artist name that are more than the specified size and that’s why its alerting us to the possibility of data loss.

    ArtistName

    So in our case we know that no data exists so we can force the changes using "updatedatabase –script –force".

    Once down it will open the script file.

    script file

    Look at the following two changes 1. Artist table is updated using Alter query and it creates another table called MigrationHistory and adds the change tracks to it. This is the table that Entity Framework will look at to determine whether the datacontext and the database are the same whenever we run the application.

    Okay, now we need to execute this, we can either manually execute the queries using SQL Server Management Studio or we can do it using the Package Manager Console.

    status

    Done, now open our mdf file from the Solution Explorer and see the changes.

    table

"Allow Nulls" is unchecked and the maximum allowed length is 100 as expected on the artistName column. Clear.

Conclusion

In this article we looked into some basic data annotations, if we need more control over the configurations then we can rely on the fluent API that we can see in future articles.

For a complete list of data annotations, you can refer to: System.ComponentModel.DataAnnotations Namespace.