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 with 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 varchar (max), and "Allow Nulls" is checked.
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 come 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 product Orders. A product order will have an order date and a ship date. The Order date can be the requested date so we can have a value all the time, but what about the 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 the Type keyword with a ? mark.
For example
Nullable<DateTime> shipDate; or else DateTime? ship date 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.
- Required(): that specifies that the database field is a necessary column.
- String Length: This will use the maximum length as the first attribute and an optional minimum length.
The Artist.CS will look as in the following.
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.
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.
Updating the database if model changes
We must use the following procedure to enable the code-first migrations.
- Open the package manager console (View -> Other Windows -> Package Manager Console).
- Type Enable-Migrations as in the following.
- 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
- We need to update the database so that changes will be executed to the database.
- If we want 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 names that are more than the specified size and that’s why it's alerting us to the possibility of data loss.
- 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.
- Look at the following two changes 1. The artist table is updated using the 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 data context 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.
- Done, now open our mdf file from the Solution Explorer and see the changes.
"Allow Nulls" is unchecked and the maximum allowed length is 100 as expected on the artist name 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.