Starting Entity Framework Codefirst Approach Part- 2
This is the second part of my Entity Framework Codefirst Tutorial for beginners. If you want to start fresh , Visit the first part here.
If you tried the first part, while creating the database using code first approach, you might have noticed that our columns of string type is created as nullable columns of type nvarachar and is having the MAX size.
Obviously it is not a good idea to create table columns like this. We need to be more specific about what we are going to built and work with. So if you want to specify the size /nullabilty, we can do that as well in few different ways
1) Data Annotation
Data Annotations are attributes we can apply to the class members. By decorating a class memmber / Property with data annotation, we can achieve the
following things
1) Impose some validations on the entity
2) Specify how the data is gonna look like in the UI when displayed
3) Specify some relationships between entities
Let us simply decorate our customer class attributes with some data annotations
So what are we getting out of this ? Run the project and see what change it brings to our database.
The Required Attribute made our column to be a not null column and the Max Length Attribute value become the size of the column.
2) Fluent API
Fluent API is another way to configure the Entitiy Properties or the relationship among the entities. What we did with data annotations in the above example can be achieved with Fluent API as well. Why do we need to use Fluent API over Data Annotations or vice versa ? Well , I guess it is more of a personal preference. Some people like to keep their classes clean. They just want to have the proeprty definition only in the classes and dont want to to define these attributes in that class. Fluent API helps those people to keep these configuration in a different place.
Entity framework will generate the database by looking at the classes we have (not all the classes, but those classes which are using inside our DBContext class to create properties of type DBSet.) created. So There is a way we can override some of the configuration. There is an overridable method called OnModelCreating inside DBContext. So we can override that in our DbContext class to specify some of the configuration we want to apply when entity framework creates tables for us from the classes.
I am going to create another entity class to show this. Let us create a class called Address under our Model folder. Add Properties like below to the Address entity.
Wait : Include a rerence to System.ComponentModel.DataAnnotations namespace in this class with a using System.ComponentModel.DataAnnotations statement. We are going to use the data annotations present in this namespace in our class
Note that we did not add any data annotations to the properties of the Address class. So when we run the project, EF will create nullable nvarchar columns with MAX length for all those string properties.
Now To override the default configuration , Go to our DBContext class (SampleContext.cs) and add the below method.
Tip : You may simply type "override" inside the class and VisualStudio intellisense will show you all virtulal methods available to be overridden. Just select OnModelCreating from that.
We can now use the DBModelBuilder object which is an argument of this method, to configure our entity / entity properties. Add some configurations in this method like below.
This code is pretty much self explanatory. It is saying that The Address Line1 Property of Address Entity should be Required field (not null) and should have a Max length of 100 (the column size). Run the project and see what output we are getting.
You can see that we are chaining methods here. That is something beautiful about this approach.
What if I have so many entities ? I will have so much of code in this method and that is worse ! We dont want to do that. Wait ! there is a much better approach. Little more refactoring ! We can move the configurations for an entity in a different class and just specify it in our OnModelCreating method. To show that, Let me add another class to our model folder called PhoneNumbers
Now to define the confiration , we will create another class called PhoneNumberConfiguration. We will inherit this class from EntityTypeConfiguration and specify the type while inheriting. In the Constructor we can define our configuration like this.
Now we will go back to our OnModelBuilder method and add the PhoneNumber configuration class instance to the Configurations property of modelBuider.
And you will see the results as
TIP : you need to include System.Data.Entity.ModelConfiguration namespace in your PhoneNumber configuration class as EntityTypeConfiguration class belongs to that.
You can download the source code of this example here for references. Leave a comment if you download the source code from this page / this article helped you.