Entity Framework is an object-relational mapper (ORM). As such, it simplifies mappings between your .NET objects and the tables and columns in your relational database. It creates database connections, executes queries towards the database, keeps track of changes that might happen in your application (an object has been added, changed, etc.), persists those changes, and, when instructed, executes those changes towards the database. In other words, it increases your productivity and reduces the amount of time necessary to implement all these features by writing your custom code.
There are also other ORMs out there, but Entity Framework is Microsoft's recommended tool for working with data in an ASP.NET application. It is widely used and well known for the following features.
The model plays a significant part in the Entity Framework. It contains configurations, mapping properties, relationships, and defines which objects map to which tables.
There are two ways to create the EF model.
This approach is usually preferred when there is no database present, or the database is empty. In this case, all objects, their properties, and existing relationships between them are defined through .NET classes. At runtime, the Entity Framework creates the model from these classes, and it also creates the database.
Developers who do not have experience with databases or have an already existing database, but want to communicate with it only through code, also find this approach to be more suitable to them.
The Entity Framework visual designer is a tool that helps you create a model by drawing boxes that represent your tables or objects and lines to build relationships between them. You can use two different approaches to create the model with Entity Framework visual designer, Database First, and Model First.
You use the Database First approach when you have an existing database, and you want to connect to it in your application. In this case, the EF visual designer creates a model from your existing database and displays it graphically with boxes and lines.
The other approach, Model First, is when you do not have a database, but you prefer to create the model using a visual designer. In this case, you start from scratch, by drawing boxes that will represent your tables and lines that will represent the relationships between them.
The model created using the EF visual design is in EDMX format, and it is an XML file that contains information about all mappings and their properties.
Once you know which approach you will take in creating your own EF model, you can start building it by installing Entity Framework in your solution. For that, you will need to install two things, Entity Framework Tools for Visual Studio and Entity Framework Runtime.
Almost all versions of Visual Studio have these tools already pre-installed. If you are working with an older version of Visual Studio, you will have to install them manually. The Entity Framework Tools allow you to use the visual designer for creating object models, so if you want to use Entity Framework with the Database and Model-first approach, then these tools must be installed in your Visual Studio environment.
To use Entity Framework in your code, you need to install the Entity Framework Runtime. The easiest way of doing this is to install it through the NuGet package manager.
Let's see how the installation process goes by installing Entity Framework in our application FirstMVCApplication.
Open the solution FirstMVCApplication in Visual Studio. In Solution Explorer, right-click the solution and choose “Manage NuGet Packages for Solution” (as shown in the image below).
When the NuGet store appears, click on Browse at the left top corner and type Entity Framework in the search box. Then, choose the project where you want the Entity Framework to be installed, select the latest stable version available, and click on the Install button.
When Visual Studio asks you to confirm the Entity Framework installation in your solution, click OK, then accept the terms and conditions and continue with the installation.
You can monitor the installation in the output window in Visual Studio. Once it is finished, you will get a message in the output window that the Entity Framework was successfully installed. There will also be a green icon in the NuGet store, right after the name of the Entity Framework package.
You can also install Entity Framework through the NuGet Package Manager console by using the following command.
Install-Package EntityFramework
If you do not specify a version with the –Version
attribute, the latest stable version will be used. In case you want to install a specific version, you can use the –Version attribute and specify the version needed.
If you cannot find the NuGet Package Manager console, make sure to open it from the menu Tools > NuGet Package Manager > Package Manager Console.
Now that we have Entity Framework installed in our solution, let's see how it works.
We will continue using the same project (FirstMVCApplication) and we will implement a simple registration functionality that will allow us to create our first EF model. We will use the EF Code First approach since we believe that it is easier to understand the whole idea behind the EF, plus you can also see all steps required to use EF in your application. The goal of the feature is to allow employees to register for different corporate events.
To do so, we need to create the following three entity classes: Employee, Event, and Registration. Besides, we will define the relationships between them. Since employees can register for multiple company events the relationship between the three entities will be defined as displayed in the image below.
In other words, an employee can register for multiple company events, and an event can have multiple employees registered for it. The entity Registration holds information about a specific registration done by a particular user for a specific event.
Now that we have an idea about how our model must look like, we will go back to our application and create the three entity classes.
To create a model with EF, we must navigate to the map Models and create a new class, which we will name Employee. The class Employee presents the employee; therefore, we will need to create the following properties to define the employee.
Additionally, we will create these two properties as well.
Employee
table uniquely identifies the employee.Our class will look like this.
public class Employee
{
public int ID { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
public string Department { get; set; }
public virtual ICollection<Registration> Registrations { get; set; }
}
The most interesting part about this class is the property Registrations. In the EF world, this property is called a navigation property. Navigation properties hold other EF entities that are related to this entity. In this case, the property Registrations will hold all registrations that are related to an employee. Usually, navigation properties are defined as virtual, so that they can take advantage of certain EF functionalities such as lazy loading. In an m<>m relationship, the navigation property is defined as a list where items can be added, edited, or deleted. In our class, we use the type ICollection.
We define the two classes Event and Registration in the same way we did with Employee.
The class Event will have the following properties.
The same as with the Employee
, we will create two more additional properties.
public class Event
{
public int EventID { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public int AvailableSeats { get; set; }
public DateTime DateTime { get; set; }
public virtual ICollection<Registration> Registrations { get; set; }
}
The class Registration
will have the following properties.
public class Registration
{
public int EmployeeID { get; set; }
public int EventID { get; set; }
public virtual Employee Employee { get; set; }
public virtual Event Event { get; set; }
}
Since the entity Registration
is associated with only one employee and one event, we define the navigation properties as single entities and not of type list, as was the case with Employee
and Event
.
The class that coordinates everything for a given EF model is the database context class. This class allows querying and saving the data, as well as adding, editing, and deleting items.
Back to our project, we will create a database context class for our project. First, we will create a new folder on the project's root level and name it DAL. DAL stands for Data Access Layer. We will create the database context class under this folder by right-clicking the folder DAL and adding a new class. Name the class CompanyContext
.
The database context class must derive from the System.Data.Entity.DbContext
class and contains all entities that need to be included in the EF model.
In our project, the database context class will look as follows.
public class CompanyContext : DbContext
{
public CompanyContext() : base("CompanyContext")
{
}
public DbSet<Employee> Employees { get; set; }
public DbSet<Registration> Registrations { get; set; }
public DbSet<Event> Events { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
This code creates a DbSet property for each entity. In Entity Framework terminology, an entity set typically corresponds to a database table, and an entity corresponds to a row in the table.
To create the database from the EF model we defined earlier, we need to specify where we want to create the database.
We will add the following connection string in the application's web.config
.
<connectionStrings>
<add name="EmployeeContext" connectionString="Data Source=(LocalDb)\MSSQLLocalDB;Initial Catalog=CompanyEvents;Integrated Security=SSPI;" providerName="System.Data.SqlClient"/>
</connectionStrings>
So, we will use our LocalDb server to create the database with the name CompanyEvents. We will connect to the database using Windows or Integrated authentication.
Next, we need to initialize a database context in our application. Open the Home controller and initialize a new database context, as shown in the image below.
When the Index action of the Home controller is called, the code for adding new employees is executed, and the DbContext will create the database.
By using MVC, EF, and ASP.NET, we can create a web application with which we can access the database. In this part of the tutorial, we will utilize the EF Database First Approach. The EF Database First Approach, like the name suggests, starts with the database. In it, we have a table, or multiple tables, that have data. Our goal would be to transfer the structure of that table/those tables into our MVC web application and create models.
In our FirstMVCApplication, we will create three tables:
For that purpose, we would need to create a simple database, where we would then create these three tables. The tables are fairly simple and do not have a lot of columns.
As a first step, we will just define the structure of the tables without any constraints (primary key, foreign key…).
The first table we are going to create is Employee. It is going to have the following columns:
The code that we will use for creating the table is shown below.
CREATE TABLE Employee
(
EmployeeID INT IDENTITY(1,1) NOT NULL,
EmployeeLastName NVARCHAR(100) NOT NULL,
EmployeeFirstName NVARCHAR(100) NOT NULL,
EmployeeDepartment NVARCHAR(200) NOT NULL
)
The second table we are going to create is Event. It is going to have the following columns:
The code that we will use for creating the table is shown below.
CREATE TABLE Event
(
EventID INT IDENTITY(1,1) NOT NULL,
EventTitle NVARCHAR(200) NOT NULL,
EventDescription NVARCHAR(1000) NOT NULL,
EventAvailableSeats INT NOT NULL,
EventDateTime DATETIME NOT NULL
)
The last table we will create is table Registration. It is going to have the following columns:
The code that we will use for creating the table is shown below.
CREATE TABLE Registration
(
RegistrationID INT IDENTITY(1,1) NOT NULL,
EmployeeID INT NOT NULL,
EventID INT NOT NULL
)
Next, we will create constraints for these three tables. We will start with the primary keys.
A primary key of a table can be one or multiple columns.
The important thing when choosing the primary key is that we are sure that whatever column/s we choose uniquely defines each entry in that table.
For example, for the table Employee, we will choose the column EmployeeID. Following is the code for creating a primary key on the before-mentioned column.
ALTER TABLE [dbo].[Employee] ADD PRIMARY KEY CLUSTERED
(
[EmployeeID] ASC
)
We will do the same for the other two tables. For the table Event, we will choose the column EventID
as a primary key, while the column RegistrationID
will be chosen as the primary key for the table Registration.
ALTER TABLE [dbo].[Event] ADD PRIMARY KEY CLUSTERED
(
[EventID] ASC
)
ALTER TABLE [dbo].[Registration] ADD PRIMARY KEY CLUSTERED
(
[RegistrationID] ASC
)
As per the cardinality matrix that we showed previously, we now need to create foreign keys for our tables. Foreign keys are needed only in table Registration. The code given below creates a relationship between tables Registration/Employee and Registration/Event.
ALTER TABLE [dbo].[Registration] WITH CHECK ADD CONSTRAINT [FK_Registration_Employee] FOREIGN KEY([EmployeeID])
REFERENCES [dbo].[Employee] ([EmployeeID])
GO
ALTER TABLE [dbo].[Registration] CHECK CONSTRAINT [FK_Registration_Employee]
GO
ALTER TABLE [dbo].[Registration] WITH CHECK ADD CONSTRAINT [FK_Registration_Event] FOREIGN KEY([EventID])
REFERENCES [dbo].[Event] ([EventID])
GO
ALTER TABLE [dbo].[Registration] CHECK CONSTRAINT [FK_Registration_Event]
GO
Now that we've created the tables in our database, it is time to create the appropriate models for those tables.
For that, we need to add an EF data model to our MVC project. We will use the ADO.NET Entity Data Model. To create it, right-click on our project (FirstMVCApplication), then select Add > New Item. A pop-up window will show up, like the one in the picture below.
In the pop-up window:
The next step will open the Entity Data Model Wizard, shown in the picture below.
Select EF Designer from a database and click on the Next button.
The next step is setting up the data connection.
Click on New Connection, which will open the Choose Data Source window, select Microsoft SQL Server, and click on the Continue button.
It will open the Connection Properties window, which is shown below.
Web.config
file of our MVC app.Here is the Web.config
file shown.
Click on the Next to go to the next step. In the picture below, tick the box before Tables to select the tables from the database for which we want to create models. Since we want to create models for all tables, we need to select them all. Then, click on the Finish button.
It will open up the EDMX diagram (shown below), which represents the models and the relationship between them.
If we compare the cardinality matrix we defined before, with the EDMX diagram which was generated, we can conclude that they are completely the same:
Employee
has a One-to-many relationship with Registration
.Event
has a One-to-many relationship with Registration
.Below is the code that is generated from the database. If we compare it with the code we wrote before. We will see that it is completely the same.
The only difference is the RegistrationID
field we defined as a separate field in the table Registration
.
Class Employee:
public partial class Employee
{
public Employee()
{
this.Registration = new HashSet<Registration>();
}
public int EmployeeID { get; set; }
public string EmployeeLastName { get; set; }
public string EmployeeFirstName { get; set; }
public string EmployeeDepartment { get; set; }
public virtual ICollection<Registration> Registration { get; set; }
}
Class Event:
public partial class Event
{
public Event()
{
this.Registration = new HashSet<Registration>();
}
public int EventID { get; set; }
public string EventTitle { get; set; }
public string EventDescription { get; set; }
public int EventAvailableSeats { get; set; }
public System.DateTime EventDateTime { get; set; }
public virtual ICollection<Registration> Registration { get; set; }
}
Class Registration:
public partial class Registration
{
public int RegistrationID { get; set; }
public int EmployeeID { get; set; }
public int EventID { get; set; }
public virtual Employee Employee { get; set; }
public virtual Event Event { get; set; }
}
The wizard has also created a context class for us. If you remember from the previous tutorial, when we worked with the Code First Approach, the context class coordinates Entity Framework. The context class that is created automatically in the Database First approach is given in the image below.
The context class contains the following properties/features.
web.config
is passed into the constructor.<connectionStrings>
<add name="TestEntities" connectionString="metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=System.Data.SqlClient;provider connection string="data source=localhost;initial catalog=Test;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
</connectionStrings>
modelBuilder.Conventions.Remove
will prevent table names from being pluralized. This means that the tables created in the database will not be in plural, e.g. Events, Registrations, Employees, but Event, Registration, Employee.The next few chapters will concentrate on adding, displaying, updating, and removing data from the database using the context class and Entity Framework.
To be able to display data related to the Employee
table, we will have to create a new controller. The controller will hold our business logic.
Back in the project, create a new controller class and name it EmployeeController
. Our controller class will inherit the MVC Controller class. For the time being, we will need a single action Index
. The action index will display the obtained employee data from the database. To access the database through our context class, we will create a private property named db
, as shown in the image below.
In the action Index
, we will use the Employee
as follows.
The statement db.Employee.ToList()
will return a list of all employees present in the database.
The next thing we need to do is to create a view and connect the action with the view. Back in the project, right-click the folder Views and create a new folder Employee. Under the folder Employee create a view Index
. This view will correspond to the action Index
in the EmployeeController
.
The view will display all the employees from the table.
Using the @model
directive, we can specify the type of data that will be passed to the view. If we take a look at the action Index
, we can see that we are passing a list of employees. Therefore, at the beginning of the view, we will use the @model
directive in the following way.
@model IEnumerable<FirstMVCApplication.Employee>
The next step is to iterate through the list of employees and display information about each employee.
The code given below creates a table and fills each row of the table with employee data. What's interesting is that we are using two HTML helpers here, @Html.DisplayFor
and @Html.DisplayNameFor
.
HTML helpers are MVC classes that help render HTML. You can, of course, use HTML tags such as span or label to display the information you need, but the advantage of using MVC HTML helpers is that they can easily bind with the Model data.
For example, if we look at the code below and how these helpers are used, we can see that @Html.DisplayNameFor
will generate HTML text for each employee property's name, where @Html.DisplayFor
will generate HTML text for each employee property's value. Every time the model gets updated, the values of the properties will get updated too.
If we run the application, we will, unfortunately, see an empty table. That's because our database is currently empty. To be able to test the code, we can manually add employees directly to the database.
Let's rerun the application. Our test data is now displayed.
The last thing that we will change is the name of each employee column:
As said earlier, the @Html.DisplayNameFor
generates the name of each Employee property, respectively. If we want to change each column's display name, we have to look at the current Employee
class.
The class Employee is defined as follows.
If we want to set more user-friendly names for the Employee
properties, we can use data annotations to define them.
Data annotations are attribute classes that you can use to decorate classes or properties to enforce pre-defined rules. In this case, we can use the attribute Display
and define a display name for each property.
If we rerun the application, we should be able to see the change.
In the previous chapter, we focused on explaining how to display data with our MVC application and EF. For testing purposes and to show that our approach works, we added some test records in the database. Those records were cleared down before continuing.
In this part, we will focus on explaining how to add data using SQL, as well as using code.
Adding records in the database is one of the fundamental actions we can perform using Entity Framework.
Of course, we can add data to the database by merely preparing INSERT
statements, which we will then execute directly on the database.
Following is an example of how we can do that.
INSERT INTO [dbo].[Employee]
([EmployeeLastName]
,[EmployeeFirstName]
,[EmployeeDepartment])
VALUES
('Doe'
,'John'
,'Engineering')
INSERT INTO [dbo].[Employee]
([EmployeeLastName]
,[EmployeeFirstName]
,[EmployeeDepartment])
VALUES
('Doe'
,'Jane'
,'Engineering')
After executing these statements on the database, we can just run the application, and the data will appear.
For us to be able to add data to our database using EF, we must write the code to do so.
The first thing we need to do is create a View, with which we will create a form that will allow us to add a new employee to the database.
The view will consist of three fields, namely the attributes of the model Employee
:
We need to right-click on the folder Employee, located in Views. Then go to Add, and then click on View.
That will open up a new Add View pop-up window, which would need to be filled out like shown below:
Because we chose the template Create, Visual Studio will create the code for the View, based on the model class we defined. The code will look similar to the one below:
After the View is created, we have to go back to the EmployeeController
and update the method for creating an employee. That would allow the application to pass the data through to the database and write it in the proper table.
Now we can test the code we wrote by adding a new employee in the database. When we run the solution, the page for creating an employee should look like the one below.
To test the form we created, we need to input data in text boxes, and then click on the Create button.
If we click Back to List, the application would then lead us to the display data section, where we would be able to see the full list of employees currently in the database.
To be able to update an existing entry in the database, we can add an Edit link to the existing employees' list.
To do so, we can use the Html helper ActionLink
. The HTML helper ActionLink will generate an HTML link element but will also allow us to send an id of the clicked item to the controller, so we can quickly obtain the id of the item that needs to be changed in the database.
If we switch to Visual Studio and open the Home > Index view, we can configure the HTML helper as shown in the image below.
Since we can identify each employee by each employee's ID in the database, we set up the HTML helper to pass the EmployeeID
to the controller.
The first string in the ActionLink
helper is the title of the link generated, and the second string is the name of the action that will be called once the user clicks the link.
The result of adding the action link to the Index
view is displayed below.
The Edit link is currently not working because we still haven't created an Edit action. We can do that now in the EmployeeController. The definition of the Edit
action is as follows.
HttpGet
attribute because Html.ActionLink
renders an anchor tag that can only trigger a GET
request to the server.Edit
action is the employee id that we expect to get on the server-side.EmployeeController
is a bad request.EmployeeID
equal to id.If we now start the application, we will click on the Edit link and edit the chosen employee.
We can edit the employee's first, last name, and/or department, and after clicking on the Save button, the new data will be saved in the database.
After clicking the Save button, we are navigated to the employee list, where we can see the edit action results.
To implement the delete action, we will add the Delete
action link right after the edit action link. We will do that in the Index view as with the Edit link.
The changed code is shown in the image below.
As with the Edit link, we use the Html.ActionLink
helper to create an anchor tag with the title Delete that will call the Delete
action from the EmployeeController
and will send the employee id that will identify the employee that we want to delete.
If we run the application, we can see that the user interface is already updated and that we can see the “Delete” link on the employee list. The Delete link does nothing since we still haven't created the Delete
action in the EmployeeController
.
Back in Visual Studio, let's create another action called Delete
as follows.
Again, the method is decorated with an HttpGet
attribute because it is called from a simple anchor tag. In the same way, as with the Edit
action, we send the id of the employee that we want to delete. If there isn't an employee in the database with that id, we throw an error if not found. In case an employee with that id exists in the database, we use the db.Employees
set and call the Remove method on that set to remove the employee. We then save the db context changes and redirect the user to the Index view, which displays the employee list.
If we run the application and navigate to the employee list and then click on the Delete link for a particular employee, the employee will be removed from the database and, therefore, not displayed on the employee list anymore.
The current employee list before deleting looks as follows.
After deleting the second employee by clicking on the Delete link, the employee list will look as follows.