Introduction
In this article, I will walk you through a simple application using MVC4 and Entity Framework 5 and will demonstrate how one can make use of code first technology. I will be using MvsScaffold for quick creation of controllers and views. We will be creating a TODO application.
Prerequisites
- Visual Studio 2010 with SP1
- MVC 4
- Nuget Package manger for Visual Studio
- SqlExpress database
Background
- Code first – Code First enables you to describe a model by using C# or Visual Basic .NET classes. Code First is a new development
methodology available beginning with the Entity Framework 4.1. You can use Code First to generate a new database from a model, or map your model to an existing database.
You can read more here.
- Entity Framework - Entity Framework (EF) is an object-relational mapper that enables .NET developers to work with relational data using
domain-specific objects. It eliminates the need for most of the data-access code that developers usually need to write. You can learn more about
this here.
- MVC 4 – Successor of MVC3, ASP.NET MVC 4 is a framework for building scalable, standards-based web applications using well-established design patterns
and the power of ASP.NET and the .NET Framework. Find all the related information here.
- MVC Scaffolding – This is a Scaffolding package for ASP.NET which is installed via NuGet using ‘Install-Package MvcScaffolding’ command.
Thanks to Scott Hanselman and Steven Anderson.
Quick Preparation
Before we start, lets make sure you have NuGet package manager and SQL component if you don’t already have it.
In Visual Studio 2010 (I use professional one), go to Tools –> Extension Manager…
Click on the ‘Online Gallery’ in search box type NuGet and hit enter. It will show the NuGet Pakage Manager, I already have it installed to you can see the green click mark. If you do not have install, double click it to install, and follow the instructions.
When you have the NuGet pakage install, you should be able to see the library package manager. Tools-> Library Package Manager –> Package Manager Console
Clicking this menu item should bring up the powershell console
Type Install-Package EntityFramework.SqlServerCompact, hit
Enter. This will install the SQL component.
Walk-through
Step 1: Create new MVC 4 application
Create a new MVC4 application, lets say it’s TODO
Step 2: Select Internet Application template with Razor as View Engine
Select Internet Application, choose the view engine as Razor
Step 3: Install MvcScaffolding
Open Package Manager Console (Tools-> Library Package Manager –> Package Manager Console)
Run following commands in the console
1: 2: Install-Package EntityFramework
3: 4: Update-Package EntityFramework
Now install MvcScaffolding
1: Install-Package MvcScaffolding
In case you are not already aware, hitting tab key brings up the options, make use of it whenever you need it in Package Manager Console.
Step 4: Create Models
Create a cs file named Models.cs in Model folder (actually you should create different files for different models, I created all of them just
to save my time)
Models.cs contains following three models.
1: using System;
2: using System.Collections.Generic;
3: using System.Linq;
4: using System.Web;
5: using System.ComponentModel.DataAnnotations;
6: using System.ComponentModel.DataAnnotations.Schema;
7:
8: namespace TODO.Models
9: {
10: public class Task
11: {
12: [Key]
13: public int TaskId { get; set; }
14: public string Name { get; set; }
15: public string Description { get; set; }
16: public int? StatusId { get; set; }
17: [ForeignKey("StatusId")]
18: public virtual Status Status { get; set; }
19: public virtual ICollection<Note> Notes { get; set; }
20: public DateTime? CreatedOn { get; set; }
21: public DateTime? ModifiedOn { get; set; }
22: }
23:
24: public class Status
25: {
26: [Key]
27: public int StatusId { get; set; }
28: public string Name { get; set; }
29: }
30:
31: public class Note
32: {
33: [Key]
34: public int NoteId { get; set; }
35: public string Description { get; set; }
36: public int? TaskId { get; set; }
37: public DateTime? CreatedOn { get; set; }
38: public DateTime? ModifiedOn { get; set; }
39: }
40: }
Data Annotations
Line 5,6: References so that I could use the Data Annotation as you can see in line 12, 17, 26 and 33. You can refer following article
for more information on Data Annotations.
Defining Relations
Notice line 18, as it can see this property should be the virtual with an attribute named
ForeignKey with the FK, also check line 16, you need to have the StatusId to link the tables.
Also if you notice line 36, Note should belong to some Task but do not need to have a Note itself.
I have used [Key] is to explicitly mention the primary keys.
Step 5: Create Controller and Views
Go to Package Manager Console, run following commands
1: Scaffold Controller Task -Repository
2: Scaffold Controller Note -Repository
3: Scaffold Controller Status –Repository
I am using ‘-Repository’ option, because I want to access the data through repositories. When you change the Models and want to recreate
the Controllers or View use ‘-Force’ option.
1: Scaffold Controller Task -Repository -Force
2: Scaffold Controller Note -Repository -Force
3: Scaffold Controller Status -Repository -Force
This step automatically create Repositories, Controllers, DBContext and Views.
Step 6: Edit Layout
Open Shared/_Layout.cshtml and add the links so that you can easily navigate to the actions and may be you want to update the Title of the application
<li>@Html.ActionLink("Home", "Index", "Home")</li>
<li>@Html.ActionLink("About", "About", "Home")</li>
<li>@Html.ActionLink("Contact", "Contact", "Home")</li>
Run the application it should work just fine. Isn’t it cool?
Before we start entering data and check investigate the database lets hide the CreatedOn and ModifiedOn fields from the view and get them updated from the code itself.
Comment out the divs in _CreateOrEdit.cshtml of Notes and Tasks view which display the ModifiedOn and CreatedOn fields.
Go to NoteRepository.cs and TaskRepository.cs, find InsertOrUpdate() method and modify them as follows
1: public void InsertOrUpdate(Task task)
2: {
3: if (task.TaskId == default(int)) {
4: 5: task.CreatedOn = task.ModifiedOn = DateTime.Now;
6: context.Tasks.Add(task);
7: } else {
8: 9: task.ModifiedOn = DateTime.Now;
10: context.Entry(task).State = EntityState.Modified;
11: }
12: }
Notice line 5 and 9, where I am modifying the
ModifiedOn
and CreatedOn
before saving and updating the model.
Update: Adding some information about line 10 as per a user comment
Line 10: context.Entry(task).State = EntityState.Modified; This is a way to tell the dbContext that some properties of the entity has been modified but SaveChanges() is not called. Entity framework takes care of updating the entity with the modified values. Calling the context.Entry() returns DbEntityEntry<TEntity> object which provide access to information about and control of entities that are being tracked by the DbContext.
In a simple words, it's the way to tell Entity Framework to update an entity with the modified values.
You would also need to have following line in _CreateOrEdit.cshtml of tasks so persist the values of
CreatedOn
.
1: @Html.HiddenFor(m=>m.CreatedOn)
Run the application again and you should be able to add, update and delete the data
This is not it, this has automatically created the database for you, you can check that out, Browse to SQLExpress database there you should be able to see a database for this application.
Check the Tables, Columns, Primary Keys and Foreign Keys they are all in place exactly as you created them in the models.
There is too much explain, however, as per the scope of this article, consider this article as starting point to plunge deep into this. Before I wrap up this article,
one last thing want to inform you about which is called database initializer.
Go to TODOContext.cs in the Model folder, create a constructor of
TODOContext
as follows:
public TODOContext()
{
System.Data.Entity.Database.SetInitializer(
new System.Data.Entity.DropCreateDatabaseIfModelChanges<TODO.Models.TODOContext>());
}
It does as the name says DropCreateDatabaseIfModelChanges
when you change any Model by adding or deleting some properties, the current database will be dropped and it will be recreated. If you modify the model without having this constructor, you might see an error as follows
I have already mentioned the database will be created in the SQLExpress, do not be surprised if you do not see the database getting created in the database specified by you in the connectionstring of the web.config.
Note: Entity framework will always try to connect to the local SQL Server Express database (.\SQLEXPRESS). Starting with EF 5,
Ef will use LocalDb if it doesn’t detect SQL Express running. SQL Express will always get precedence if it is installed, even if you are using Visual Studio 2012.
References
Following are the links where you can find more information: