Entity Framework Notes
Entity Framework Notes
1|Page
2|Page
Object Relational Mapping framework automatically creates classes based on database tables,
and the vice versa is also true, that is, it can also automatically generate necessary SQL to
create database tables based on classes.
Let's understand what entity framework can provide with an example. Assume we have
the following 2 tables
We want to display the above data from both the tables in a webform as shown below.
To achieve this
1. We need to create Department and Employee classes
2. Write ADO.NET code to retrieve data from the database
3. Once the data is retrieved we need to create Department and Employee objects and populate
them with data.
Entity Framework can do all of the above automatically, if we provide it with the database
3|Page
schema.
Please note: You must restart visual studio for the changes to take effect.
4|Page
At this point Entity Framework version 6.1 is installed and a reference to EntityFramework
assembly is also automatically added.
5|Page
)
Step 5: Right click on the project in solution explorer and add ADO.NET Entity Data Model.
Change the name from Model1.edmx to EmployeeModel.edmx
6|Page
e) Select the database from "Select or enter database name" dropdownlist.
f) Finally "Test connection" and click "OK"
g) At this point we should be back on "Choose Your Data Connection" window. Make
sure "Save entity connection settings in Web.Config as" checkbox is selected and change
the name of the connection string to "EmployeeDBContext" and then Click"Next"
Step 9: Add a webform. Drag and drop a GridView and an EntityDataSource control on the
webform.
Step 10: Build the solution. Flip the WebForm1.aspx to design mode.
a) Right click on EntityDataSource control and select "Show smart tag" option from the
context menu.
b) Click on "Configure Data Source" link
c) Select "Named Connection" radiobutton and select "EmployeeDBContext" from the
dropdownlist.
d) Select "EmployeeDBContext" option from "DefaultContainerName" dropdownlist and
click "Next"
e) On "Configure Data Selection" screen,
select "Departments" from"EntitySetName" dropdownlist and click "Finish"
f) Right click on "GridView1" control and select "Show smart tag" option.
g) Click on "Auto Format" link and select "Colorful" option from "AutoFormat" window and
click "OK".
h) Select "EntityDataSource1" from "Choose Data Source" dropdownlist.
I) Click on "Eidt Columns" link and add a "Template Field". SetHeaderText=Employees and
click OK.
j) Now click "Edit Templates" link.
k) Drag and drop a GridView control
7|Page
l) Select "Edit DataBindings" link
m) Select "Custom binding" radiobutton and type Eval("Employees") in "Code
expression" textbox and click OK.
n) Select "End Template Editing" option from "GridView1" smart tasks pane.
Step 11: Right click on "EntityDataSource1" control and select "Properties". In properties
window set Include=Employees
Run the web application and notice that Departments and Employees are displayed as
expected. We have achieved all this without writing a single line of code.
In this demo, we have used schema first approach of entity framework. We can also
useModel First or Code First approaches. We will discuss these in our subsequent videos.
In the Model First Approach, we first create the Entity Model. That is we create
1. Entities
2. Relationships between entities
3. Inheritance hierarchies etc.
We do all this directly on the design surface of the EDMX file. We will be continuing with the
same example that we started in Part 1 of Entity Framework Tutorial.
Step 1: First delete the "EmployeeModel.edmx" file from the existing solution
Step 2: Add a new "ADO.NET Entity Data Model" file with name = EmployeeModel.
Step 3: On "Choose Model Contents" screen, select "Empty Model" and click"Finish"
8|Page
Step 4: At this point, we have a blank EmployeeModel.edmx file added to the solution. Now,
right click on the designer surface and then select : Add - Entity. Set,
Entity Name = Department
Base Type = None
Entity Set = Departments
Create Key property = Select the check box
Property Name = Id
Property Type = Int32
9|Page
Step 5: Right click on "Department" entity and select "Add - Scalar Property". Change the
property name to "Name". Right click on the "Name" property that we just added and
select "properties" from the context menu. Notice that the "Type" of "Name" property is set
to "String".
Step 6: Similarly add "Location" property for the "Department" entity. At this point,
the"Department" entity should look as shown below.
10 | P a g e
FirstName (Type = string)
LastName (Type = string)
Gender (Type = string)
Salary (Type = int)
Step 8: At this point, Department and Employee entities should look as shown below.
Step 9: We need to add "Employees" navigation property for the "Department" entity,
and "Department" navigation property for the "Employee" entity. To do this, right click on
the design surface and select "Add - Association". In the "Add Association" window, set
values as shown in the image below and click "OK"
11 | P a g e
Step 10: At this point, we should have the following created.
a) Employees navigation property in the Department entity
b) Department navigation property in the Employee entity
c) DepartmentId scalar property
12 | P a g e
Step 11: Right click on the design surface, and select "Genedrate Database from
Model..." option
Step 13: At this point, we should have the required SQL generated to create
a) Departments table
b) Employees table
c) Primary key constraints for Departments and Employees tables
d) Foreign key constraint
e) Indexes
Step 14: Click Finish. Now, we should have "EmployeeModel.edmx.sql" file generated with
the required SQL. If you already have "Departments" and "Employees" tables in the
database, delete them. Right click on the file and select "Execute SQL" option from the context
menu.
Step 15: Populate the "Departments" and "Employees" tables with sample data using the
script below.
Insert into Departments values ('IT', 'New York')
Insert into Departments values ('HR', 'London')
Insert into Departments values ('Payroll', 'Sydney')
Step 16: Run the application by pressing CTRL + F5. We will get the following runtime error.
The specified default EntityContainer name 'EmployeeDBContext' could not be found in the
mapping and metadata information.
Parameter name: defaultContainerName
13 | P a g e
Entity Framework supports
1. Database first or schema first approach - Discussed in Part 1
2. Model first appraoch - Discussed in Part 2
3. Code first approach - In this video
Code-first approach allows us to create our custom classes first and based on those
custom classes entity framework can generate database automatically for us. Let's
understand this with an example. We will be modifying the example we worked with in Part 2.
Step 2: Add a class file to the project. Name it Employee.cs. Copy and paste the following
code.
public class Employee
{
// Scalar Properties
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Gender { get; set; }
public int Salary { get; set; }
// Navigation Property
public Department Department { get; set; }
}
Step 3: Add a class file to the project. Name it Department.cs. Copy and paste the following
code.
public class Department
{
// Scalar Properties
public int Id { get; set; }
public string Name { get; set; }
public string Location { get; set; }
// Navigation Property
public List<Employee> Employees { get; set; }
}
Step 4: Add a class file to the project. Name it EmployeeDBContext.cs. Copy and paste the
following code.
// EmployeeDBContext class must inherit from DbContext
// present in System.Data.Entity namespace
public class EmployeeDBContext : DbContext
{
public DbSet<Department> Departments { get; set; }
public DbSet<Employee> Employees { get; set; }
14 | P a g e
}
Step 5: Add a class file to the project. Name it EmployeeRepository.cs. Copy and paste the
following code.
public class EmployeeRepository
{
public List<Department> GetDepartments()
{
EmployeeDBContext employeeDBContext = new EmployeeDBContext();
return employeeDBContext.Departments.Include("Employees").ToList();
}
}
Please Note: If ProviderName is not specified the following runtime error will be thrown.
The connection string 'EmployeeDBContext' in the application's configuration file does not
contain the required providerName attribute."
Step 10: Delete the already existing database from SQL Server Management Studio.
Step 11: Run the application by pressing CTRL + F5. Notice that we don't have any data
displayed on WebForm1. This is because we don't have any data in the Departments and
Employees tables. At this point we have the following created automatically.
a) Sample database
b) Departments table
c) Employees table
Step 12: Use the SQL script to populate the tables with data.
Insert into Departments values ('IT', 'New York')
15 | P a g e
Insert into Departments values ('HR', 'London')
Insert into Departments values ('Payroll', 'Sydney')
Step 13: Refresh the Web Form and we should see the data we expect.
Part 4 - Customizing table, column and foreign key column names when using
entity framework code first approach
In this vide we will discuss, customizing table, column and foreign key column names when
using entity framework code first approach. This is continuation to Part 3. Please watch Part
3 before proceeding.
In Part 3, we have discussed generating Departments and Employees tables using Entity
Framework Code first approach.
Entity Framework generated the following Employees table. Notice the column
names.Department_Id column has an underscore in it's name. Let's say we want the column to
be generated as DepartmenId (without an underscore)
Entity Framework generated the above Employees table based on the following custom
Employee class that we created.
public class Employee
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Gender { get; set; }
public int Salary { get; set; }
public Department Department { get; set; }
}
16 | P a g e
To achieve this use the ForeignKey attribute present
inSystem.ComponentModel.DataAnnotations.Schema namespace. Modify the Employee
class as shown below.
public class Employee
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Gender { get; set; }
public int Salary { get; set; }
public int DepartmentId { get; set; }
[ForeignKey("DepartmentId")]
public Department Department { get; set; }
}
You will get the following error. We will discuss the reasons for this error and how to fix it the
right way in a later video session.
The model backing the 'EmployeeDBContext' context has changed since the database was
created. Consider using Code First Migrations to update the database
(http://go.microsoft.com/fwlink/?LinkId=238269).
For now to get around the error, delete the Sample database using SQL Server Management
Studio, and then try to run the application again. A blank webform will be displayed. Now check
the Employees tables using SQL Server Management Studio and notice that
the DepartmentId column is created without an underscore as expected.
To customize the table name, use Table attribute and to customize column
name useColumn attribute.
17 | P a g e
public string FirstName { get; set; }
public string LastName { get; set; }
public string Gender { get; set; }
public int Salary { get; set; }
public int DepartmentId { get; set; }
[ForeignKey("DepartmentId")]
public Department Department { get; set; }
}
Entity Framework would then generate the following. Notice the table
name andFirst_Name column.
In this video we will discuss, how to handle model changes after the database is already
created. This is continuation to Part 4. Please watch Part 4 before proceeding.
The following is the table Entity Framework has generated based on the above Employeeclass
18 | P a g e
Now let us add JobTitle property to the Employee class. The modified Employee class is
shown below.
[Table("tblEmployees")]
public class Employee
{
public int Id { get; set; }
[Column("First_Name")]
public string FirstName { get; set; }
public string LastName { get; set; }
public string Gender { get; set; }
public int Salary { get; set; }
public int DepartmentId { get; set; }
[ForeignKey("DepartmentId")]
public Department Department { get; set; }
public string JobTitle { get; set; }
}
This is because the model (i.e Employee class) has changed since the database was created.
This means the Model and the database are no longer in sync and hence we get the error. To
check if the model has changed since the database was created, entity framework
uses __MigrationHistory table that is auto-generated.
To fix this error, we have to tell entity framework what to do when the model changes.
Add Global.asax file to the web application project. Include the following code
inApplication_Start() method. Here, we are telling the entity framework to drop and recreate
database every time the model changes.
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<EmployeeDBContext>());
Another option is, to drop and recreate the database always. To drop and recreate the database
always we would change the code in Application_Start() method as shown below.
Database.SetInitializer(new DropCreateDatabaseAlways<EmployeeDBContext>());
Run the application, and notice that the database is dropped and recreated. But the webform
19 | P a g e
does not display any data, as there is no data in Departments and tblEmployees tables. For now
let's manually populate the tables using the followng SQL script.
Insert into Departments values ('IT', 'New York')
Insert into Departments values ('HR', 'London')
Insert into Departments values ('Payroll', 'Sydney')
Referesh the webform. Notice that JobTitle is not displayed on the WebForm. To fix this add a
boundfield to the GridView control that displays Employees details as shown below.
<asp:GridView ID="GridView2" runat="server" AutoGenerateColumns="False"
DataSource='<%# Eval("Employees") %>'>
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="First Name" />
<asp:BoundField DataField="LastName" HeaderText="Last Name" />
<asp:BoundField DataField="Gender" HeaderText="Gender" />
<asp:BoundField DataField="Salary" HeaderText="Salary" />
<asp:BoundField DataField="JobTitle" HeaderText="Job Title" />
</Columns>
</asp:GridView>
Part 6 - How to seed database with test data using entity framework
Suggested Videos
So far in this video series, we have been manually populating the database with test data
using the insert sql script. Entity Framework can automate this. We will be working with the
example we worked with in Part 5. Here are the steps.
Step 1: Right click on the project in solution explorer and add a class file with name
=EmployeeDBContextSeeder.cs
20 | P a g e
Name = "IT",
Location = "New York",
Employees = new List<Employee>()
{
new Employee()
{
FirstName = "Mark",
LastName = "Hastings",
Gender = "Male",
Salary = 60000,
JobTitle = "Developer"
},
new Employee()
{
FirstName = "Ben",
LastName = "Hoskins",
Gender = "Male",
Salary = 70000,
JobTitle = "Sr. Developer"
},
new Employee()
{
FirstName = "John",
LastName = "Stanmore",
Gender = "Male",
Salary = 80000,
JobTitle = "Project Manager"
}
}
};
21 | P a g e
JobTitle = "Sr. Recruiter"
}
}
};
Department department3 = new Department()
{
Name = "Payroll",
Location = "Sydney",
Employees = new List<Employee>()
{
new Employee()
{
FirstName = "Steve",
LastName = "Pound",
Gender = "Male",
Salary = 45000,
JobTitle = "Sr. Payroll Admin",
},
new Employee()
{
FirstName = "Valarie",
LastName = "Vikings",
Gender = "Female",
Salary = 35000,
JobTitle = "Payroll Admin",
}
}
};
context.Departments.Add(department1);
context.Departments.Add(department2);
context.Departments.Add(department3);
base.Seed(context);
}
}
}
Step 3: Copy and paste the following line in Application_Start() method Global.asax file
Database.SetInitializer(new EmployeeDBContextSeeder());
Step 4: Remove the following Table and Column attributes from Employee.cs file.
[Table("tblEmployees")]
[Column("First_Name")]
22 | P a g e
public string Gender { get; set; }
public int Salary { get; set; }
public int DepartmentId { get; set; }
[ForeignKey("DepartmentId")]
public Department Department { get; set; }
public string JobTitle { get; set; }
}
In this video we will discuss using our own custom stored procedures to perform Insert,
Update and Delete operations using entity framework. We will be using the
following Employees table for this demo.
Step 1: Use the following SQL Script to create and populate Employee table.
Create table Employees
(
ID int primary key identity,
Name nvarchar(50),
Gender nvarchar(50),
Salary int
)
23 | P a g e
@Name nvarchar(50),
@Gender nvarchar(50),
@Salary int
as
Begin
Insert into Employees values (@Name, @Gender, @Salary)
End
Go
b) On "Choose Your Data Connections" screen give a meaningful name for the connection
24 | P a g e
string that will be stored in the web.config file. I have named itEmployeeDBContext.
Click Next.
c) On "Choose Your Database Objects" screen, select Employees Table and the 3 stored
procedures (InsertEmployee, UpdateEmployee, DeleteEmployee). Provide a meaningful
name for the Model namespace. I have named it EmployeeModel. CLickFinish.
At this point on the ADO.NET Entity Model designer surface, we should be able to see
theEmployee entity but not the stored procedures.
25 | P a g e
Step 5: Add a web form to the project. Drag and drop the following 3 controls and build the
solution.
1. GridView
2. DetailsView
3. EntityDataSource
a). Right click on EntityDataSource control and select "Show Smart Tag" option
c) Select EmployeeDBContext from the Named Connection dropdownlist and click Next
d) Select the options on "Configure Data Selection" screen as shown in the image below and
click Finish
26 | P a g e
Step 7: Configure GridView control
a). Right click on GridView control and select "Show Smart Tag" option
27 | P a g e
Step 8: Configure DetailsView control
a) Right click on DetailsView control and select "Show Smart Tag" option
b) Click on "Auto Format" link and select "Colourful" scheme
c) Select "EntityDataSource1" from "Choose Data Source" dropdownlist
d) Select Enable Inserting checkbox
e) Set DeafultMode=Insert. Use properties window to set this.
f) Set InsertVisible="false" for the ID BoundField. You can do this directly in the HTML
Source.
g) Generate ItemInserted event handler method for DetailsView control. Copy and paste the
following code.
protected void DetailsView1_ItemInserted (object sender, DetailsViewInsertedEventArgse)
{
GridView1.DataBind();
}
At this point if you run the application, and if you insert, update and delete employees, by
default entity framework will use the sql it auto-generates and not our custom stored
procedures.
To tell the entity framework to use the stored procedures, we have to map them to the
Employee entity.
2. In the "Mapping Details" windows specify the Insert, Update and Delete stored
procedures that you want to use with "Employee" entity
28 | P a g e
At this point,
1. Run SQL Prrofiler
2. Run the application
3. Insert, Update and Delete Employee, and notice that the respective stored procedures are
being called now.
Part 8 - Using stored procedures with entity framework code first approach
Suggested Videos
In this video we will discuss using stored procedures to perform Insert, Update and Delete
operations using entity framework code first approach.
Step 1: Create a new empty asp.net web application project. Name it Demo. Install entity
framework if it's not already installed.
Step 2: Add a class file to the project. Name it Employee.cs. Copy and paste the following code.
namespace Demo
{
public class Employee
{
public int ID { get; set; }
public string Name { get; set; }
public string Gender { get; set; }
public int Salary { get; set; }
29 | P a g e
}
}
Step 3: Add a class file to the project. Name it EmployeeDBContext.cs. Copy and paste the
following code.
using System.Data.Entity;
namespace Demo
{
public class EmployeeDBContext : DbContext
{
public DbSet<Employee> Employees { get; set; }
Step 4: Add a class file to the project. Name it EmployeeRepository.cs. Copy and paste the
following code.
using System.Collections.Generic;
using System.Linq;
namespace Demo
{
public class EmployeeRepository
{
EmployeeDBContext employeeDBContext = new EmployeeDBContext();
30 | P a g e
}
Step 6: Add a webform to the project. Drag and drop the following 3 controls and build the
solution.
1. GridView
2. DetailsView
3. ObjectDataSource
31 | P a g e
Step 10: If you already have Sample database in SQL Server. Delete it from SQL Server
Management Studio.
Step 11: Run the application by pressing CTRL + F5. Notice that we don't have any data
displayed on WebForm1. This is because we don't have any data in the Employees table.
At this point we have the Sample database and Employees table created automatically. The
following stored procedures are also automatically created.
Employee_Delete
Employee_Insert
Employee_Update
By default, the following should be the naming convention for the stored procedures.
INSERT stored procedure - [Entity_Name]_Insert. Insert Stored procedure should return the
auto-generated identity column value.
UPDATE stored procedure - [Entity_Name]_Update
DELETE stored procedure - [Entity_Name]_Delete
Step 12: Use the below SQL script to populate Employees tables with test data.
Insert into Employees values ('Mark', 'Male', 60000)
Insert into Employees values ('Steve', 'Male', 45000)
Insert into Employees values ('Ben', 'Male', 70000)
Insert into Employees values ('Philip', 'Male', 45000)
Insert into Employees values ('Mary', 'Female', 30000)
Insert into Employees values ('Valarie', 'Female', 35000)
Insert into Employees values ('John', 'Male', 80000)
At this point,
1. Run SQL Prrofiler
2. Run the application
3. Insert, Update and Delete Employees, and notice that the respective stored procedures are
being called as expected.
Part 9 - Overriding stored procedure defaults with entity framework code first
approach
Suggested Videos
In this video we will discuss, changing the default Insert, Update and Delete stored procedure
names that are auto-generated by entity framework code first approach. This is continuation
to Part 8. Please watch Part 8 before proceeding.
32 | P a g e
base.OnModelCreating(modelBuilder);
}
}
By default, the code above generates the following 3 stored procedures for Inserting, Updating
and Deleting Employee objects.
Employee_Insert
Employee_Update
Employee_Delete
If you want to override or change the default names of auto-generated stored procedures,
change the code in EmployeeDBContext class as shown below.
public class EmployeeDBContext : DbContext
{
public DbSet<Employee> Employees { get; set; }
base.OnModelCreating(modelBuilder);
}
}
At this point delete the Sample database and run WebForm1 again. Notice that the generated
stored procedures now have the names we specified.
33 | P a g e
base.OnModelCreating(modelBuilder);
}
}
The default parameter names of the stored procedures can also be changed using the
following code.
public class EmployeeDBContext : DbContext
{
public DbSet<Employee> Employees { get; set; }
At this point drop the Sample database and run WebForm1 again. Notice that the stored
34 | P a g e
procedure parameters have the names we specified.
Entity splitting refers to mapping an entity to two or more tables when the tables share a
common key. Let us understand Entity splitting with an example.
We have the following 2 tables. Notice that both the table share the common key -EmployeeID.
Employees Table
EmployeeContactDetails Table
35 | P a g e
SQL Script to create the database objects and populate them with test data
Create table Employees
(
EmployeeID int primary key identity,
FirstName nvarchar(50),
LastName nvarchar(50),
Gender nvarchar(50)
)
GO
Now, when we use ADO.NET Entity Framework to generate entities from the database using
database first approach, by default 2 entities will be created,
i.e Empoyee andEmployeeContactDetail entities.
36 | P a g e
There is a one to one mapping between tables and entities. We want a singleEmployee to map
to both Employees & EmployeeContactDetails table.
To achieve this
1. Cut Email, Mobile and LandLine properties from EmployeeContactDetail entity and paste
them in Employee entity
2. Delete EmployeeContactDetail entity. On "Delete Unmapped Tables and Views"window
click NO.
3. Right click on Employee entity and select "Table Mapping" option from the context menu.
Map EmployeeId, Email, Mobile and LandLine properties to the respective columns
of EmployeeContactDetails table.
At this point we have only one Entity. Build the solution. Add a WebForm. Drag and drop the
following 3 controls.
1. GridView
2. DetailsView
3. EntityDataSource
37 | P a g e
a). Right click on EntityDataSource control and select "Show Smart Tag" option
b) Click on Configure Data Source link
c) Select EmployeeDBContext from the Named Connection dropdownlist and clickNext
d) Select Employees from EntitySetName dropdownlist and enable Inserts,
Updatesand Deletes.
At this point run the application. Insert, update and delete an Employee, and notice that both
the tables (Employees and EmployeeContactDetails) are updated as expected.
Part 11 - Entity splitting in entity framework with code first approach
Suggested Videos
Entity splitting refers to mapping an entity to two or more tables when the tables share a
common key. We discussed, Entity splitting with database first approach in Part 10. In this video
we will discuss Entity splitting with code first approach.
Step 1: Create a new empty asp.net web application project. Name it Demo. Install entity
framework if it's not already installed.
Step 2: Add a class file to the project. Name it Employee.cs. Copy and paste the following
code.
namespace Demo
{
public class Employee
{
// These property values should be stored in Employees Table
38 | P a g e
public int EmployeeId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Gender { get; set; }
Step 3: Add a class file to the project. Name it EmployeeDBContext.cs. Copy and paste the
following code.
using System.Data.Entity;
namespace Demo
{
public class EmployeeDBContext : DbContext
{
public DbSet<Employee> Employees { get; set; }
}
}
Step 4: Add a class file to the project. Name it EmployeeRepository.cs. Copy and paste the
following code.
using System.Collections.Generic;
using System.Linq;
namespace Demo
{
public class EmployeeRepository
{
EmployeeDBContext employeeDBContext = new EmployeeDBContext();
39 | P a g e
employeeToUpdate.Email = employee.Email;
employeeToUpdate.Mobile = employee.Mobile;
employeeToUpdate.Landline = employee.Landline;
employeeDBContext.SaveChanges();
}
Step 6: Add a webform to the project. Drag and drop the following 3 controls and build the
solution.
1. GridView
2. DetailsView
3. ObjectDataSource
40 | P a g e
b) Click on "Auto Format" link and select "Colourful" scheme
c) Select "ObjectDataSource1" from "Choose Data Source" dropdownlist
d) Select Enable Inserting checkbox
e) Set DeafultMode=Insert. Use properties window to set this.
f) Set InsertVisible="false" for the EmployeeId BoundField. You can do this directly in the
HTML Source.
g) Generate ItemInserted event handler method for DetailsView control. Copy and paste the
following code.
protected void DetailsView1_ItemInserted(object sender, DetailsViewInsertedEventArgs e)
{
GridView1.DataBind();
}
Step 10: If you already have Sample database in SQL Server. Delete it from SQL Server
Management Studio.
Step 11: Run the application by pressing CTRL + F5. By default entity framework creates one
Table i.e Employees table. But we want entity framework to create the following 2 tables.
a) Employees table with columns EmployeeId, FirstName, LastName and Gender
b) EmployeeContactDetails table with columns EmployeeId, Email, Mobile and Landline
map.ToTable("Employees");
})
// Specify properties to map to EmployeeContactDetails table
.Map(map =>
{
map.Properties(p => new
{
p.EmployeeId,
41 | P a g e
p.Email,
p.Mobile,
p.Landline
});
map.ToTable("EmployeeContactDetails");
});
base.OnModelCreating(modelBuilder);
}
}
Step 13: Delete the Sample database and run the web application.
Step 14: Notice that now we have 2 tables generated by entity framework as expected.
Step 15: Execute the following SQL script to populate the tables with test data.
Insert into Employees values ('Mark', 'Hastings', 'Male')
Insert into Employees values ('Steve', 'Pound', 'Male')
Insert into Employees values ('Ben', 'Hoskins', 'Male')
Insert into Employees values ('Philip', 'Hastings', 'Male')
Step 16: At this point run the application. Insert, update and delete an Employee, and notice
that both the tables (Employees and EmployeeContactDetails) are updated as expected.
Part 12 - Table splitting in entity framework
Suggested Videos
In this video we will discuss Table splitting in entity framework with database first
approach. Table Splitting is the opposite of Entity Splitting.
Entity Splitting refers to mapping an entity to two or more tables when the tables share a
common key.
43 | P a g e
One common entity framework interview question is, What is the main reason for using
Table Splitting?
Table Splitting is useful when you want to delay the loading of some properties with large data
when using lazy loading.
For example, if you have Employee entity and if it contains Photo property that would return
large binary data, and if we use this Photo property only on a few pages in our application, then
it does not make sense from a performance perspective to load this property every time we load
the Employee entity. Using lazy loading load it only on the pages where we need to display
Employee photo.
44 | P a g e
Gender nvarchar(50),
Email nvarchar(50),
Mobile nvarchar(50),
LandLine nvarchar(50)
)
Insert into Employees values ('Mark', 'Hastings', 'Male', 'x@x.com', 'XXX', 'XXX')
Insert into Employees values ('Steve', 'Pound', 'Male', 'y@y.com', 'YYY', 'YYY')
Insert into Employees values ('Ben', 'Hoskins', 'Male', 'z@z.com', 'ZZZ', 'ZZZ')
Insert into Employees values ('Philip', 'Hastings', 'Male', 'a@a.com', 'AAA', 'AAA')
Insert into Employees values ('Mary', 'Lambeth', 'Female', 'b@b.com', 'BBB','BBB')
Now, when we use ADO.NET Entity Framework to generate entities from the database using
database first approach, by default one entity will be created, i.e Empoyee entity.
Let's say, we will not be using Email, Mobile and Landline properties as often as we would be
using FirstName, LastName, and Gender properties. If all of these properties are present
in one Employee entity, then every time we load this entity, all the properties will be
automatically loaded. So let's create 2 entities (Employee & EmployeeContactDetail). This
enables us to load EmployeeContactDetails only when needed.
To achieve this:
1. Right click on the entity designer and select "Add Entity" option from the context menu. Set
a) Entity Name = EmployeeContactDetail
b) Bae type = (None)
c) Entity Set = EmployeeContactDetails
d) Create Key Property = Checked
e) Property Name = EmployeeID
45 | P a g e
2. Cut Email, Mobile and LandLine properties from Employee entity and paste them
inEmployeeContactDetail entity
3. Right click on the entity designer and select "Add - Association" option from the context
menu. Fill the details shown below.
46 | P a g e
4. Right click on the association and select "Properties". In the Properties window, click on
the ellipsis button next to "Referential Constraint" property and fill in the details as shown
below.
47 | P a g e
5. Right click on "EmployeeContactDetail" entity and select "Table Mapping" option from the
context menu. Select "Employees" table and map EmployeeId, Email,
Mobileand Landline properties of the entity to the respective columns of the table.
6. Add a webform. Copy and paste the following HTML in the ASPX page.
<div style="font-family:Arial">
<asp:CheckBox ID="checkBoxIncludeContactDetails"
Text="Include Contact Details" runat="server" />
<br />
<asp:Button ID="Button1" runat="server" Text="Get Employee Data"
onclick="Button1_Click" />
<asp:GridView ID="GridView1" runat="server">
</asp:GridView>
</div>
48 | P a g e
{
private DataTable GetEmployeeData()
{
EmployeeDBContext employeeDBContext = new EmployeeDBContext();
List<Employee> employees = employeeDBContext.Employees.ToList();
dataTable.Columns.AddRange(columns);
dataTable.Rows.Add(dr);
}
return dataTable;
}
49 | P a g e
dr["Email"] = employee.EmployeeContactDetail.Email;
dr["Mobile"] = employee.EmployeeContactDetail.Mobile;
dr["LandLine"] = employee.EmployeeContactDetail.LandLine;
dataTable.Rows.Add(dr);
}
return dataTable;
}
At this point, run the application and when you retrieve Employees without checking"Include
Contact Details" checkbox, the following query is generated by the entity framework. Use SQL
Profiler to view the generated query. Notice that Email, Mobile andLandLine column values
are not loaded.
SELECT
[Extent1].[EmployeeID] AS [EmployeeID],
[Extent1].[FirstName] AS [FirstName],
[Extent1].[LastName] AS [LastName],
[Extent1].[Gender] AS [Gender]
FROM [dbo].[Employees] AS [Extent1]
When you check "Include Contact Details" checkbox, the following query is generated
SELECT
[Extent1].[EmployeeID] AS [EmployeeID],
[Extent1].[FirstName] AS [FirstName],
[Extent1].[LastName] AS [LastName],
[Extent1].[Gender] AS [Gender],
[Extent1].[Email] AS [Email],
[Extent1].[Mobile] AS [Mobile],
[Extent1].[LandLine] AS [LandLine]
FROM [dbo].[Employees] AS [Extent1]
Part 13 - Table splitting in entity framework with code first approach
Suggested Videos
In this video we will discuss Table splitting in entity framework with code firstapproach. We
discussed Table Splitting with database first approach in Part 12.
50 | P a g e
Mapping multiple entities to a single table is called table splitting.
Step 1: Create a new empty asp.net web application project. Name it Demo. Install entity
framework if it's not already installed.
Step 2: Add a class file to the project. Name it Employee.cs. Copy and paste the following
code.
namespace Demo
{
public class Employee
{
public int EmployeeID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Gender { get; set; }
Step 3: Add a class file to the project. Name it EmployeeContactDetail.cs. Copy and paste the
following code.
namespace Demo
{
public class EmployeeContactDetail
{
public int EmployeeID { get; set; }
public string Email { get; set; }
public string Mobile { get; set; }
public string LandLine { get; set; }
Step 4: Add a class file to the project. Name it EmployeeDBContext.cs. Copy and paste the
following code.
using System.Data.Entity;
namespace Demo
{
public class EmployeeDBContext : DbContext
{
public DbSet<Employee> Employees { get; set; }
51 | P a g e
.ToTable("Employees");
modelBuilder.Entity<EmployeeContactDetail>()
.HasKey(pk => pk.EmployeeID)
.ToTable("Employees");
modelBuilder.Entity<Employee>()
.HasRequired(p => p.EmployeeContactDetail)
.WithRequiredPrincipal(c => c.Employee);
}
}
}
Step 6: Add a web form to the project. Copy and paste the following HTML in the aspx page
<div style="font-family:Arial">
<asp:CheckBox ID="checkBoxIncludeContactDetails"
Text="Include Contact Details" runat="server" />
<br />
<asp:Button ID="Button1" runat="server" Text="Get Employee Data"
onclick="Button1_Click" />
<asp:GridView ID="GridView1" runat="server">
</asp:GridView>
</div>
Step 7: Copy and paste the following code in the code-behind file.
public partial class WebForm1 : System.Web.UI.Page
{
private DataTable GetEmployeeData()
{
EmployeeDBContext employeeDBContext = new EmployeeDBContext();
List<Employee> employees = employeeDBContext.Employees.ToList();
dataTable.Columns.AddRange(columns);
52 | P a g e
dr["FirstName"] = employee.FirstName;
dr["LastName"] = employee.LastName;
dr["Gender"] = employee.Gender;
dataTable.Rows.Add(dr);
}
return dataTable;
}
dataTable.Rows.Add(dr);
}
return dataTable;
}
53 | P a g e
GridView1.DataSource = GetEmployeeData();
}
GridView1.DataBind();
}
}
At this point, run the application. Sample database and Employees table should be created by
the entity framework.
When you retrieve Employees without checking "Include Contact Details" checkbox, the
following query is generated by the entity framework. Use SQL Profile to view the generated
query. Notice that Email, Mobile and LandLine column values are not loaded.
SELECT
[Extent1].[EmployeeID] AS [EmployeeID],
[Extent1].[FirstName] AS [FirstName],
[Extent1].[LastName] AS [LastName],
[Extent1].[Gender] AS [Gender]
FROM [dbo].[Employees] AS [Extent1]
When you check "Include Contact Details" checkbox, the following query is generated
SELECT
[Extent1].[EmployeeID] AS [EmployeeID],
[Extent1].[FirstName] AS [FirstName],
[Extent1].[LastName] AS [LastName],
[Extent1].[Gender] AS [Gender],
[Extent1].[Email] AS [Email],
[Extent1].[Mobile] AS [Mobile],
[Extent1].[LandLine] AS [LandLine]
FROM [dbo].[Employees] AS [Extent1]
Part 14 - Conditional Mapping in entity framework
Suggested Videos
In this video we will discuss Conditional Mapping feature in entity framework with database
first approach. Let us understand what Conditional Mapping can do with an example.
We will be using the following Employees table in this demo. IsTerminated column determines
if an employee is a terminated employee or not.
54 | P a g e
SQL Query to create Employees table
Create table Employees
(
EmployeeID int primary key identity,
FirstName nvarchar(50),
LastName nvarchar(50),
Gender nvarchar(50),
IsTerminated bit not null
)
GO
If the application that we are developing always need only the employees who are not
terminated, then in the query we will have to always include the filter across our entire
application. Conditional Mapping can be used to apply such a permanent filter on the entity, so
that the generated SQL query always have the WHERE clause.
55 | P a g e
At this point, if you build the solution or validate the model, you will get the following error
Problem in mapping fragments starting at line 46:Condition member 'Employees.IsTerminated'
with a condition other than 'IsNull=False' is mapped. Either remove the condition on
Employees.IsTerminated or remove it from the mapping
This is because, a table column cannot be mapped more than once. We have
usedIsTerminated column in conditional mapping, so it cannot be used in property
mapping as well. For this reason delete it from Employee entity.
Add a web form to the project. Drag and drop a GridView control. Copy and paste the following
code in the code-behind file.
protected void Page_Load(object sender, EventArgs e)
{
EmployeeDBContext employeeDBContext = new EmployeeDBContext();
GridView1.DataSource = employeeDBContext.Employees;
GridView1.DataBind();
}
Open SQL profiler and run the webform. Notice that the select query has a whereclause,
which will always return employees who are not terminated.
SELECT
[Extent1].[EmployeeID] AS [EmployeeID],
[Extent1].[FirstName] AS [FirstName],
[Extent1].[LastName] AS [LastName],
[Extent1].[Gender] AS [Gender]
FROM [dbo].[Employees] AS [Extent1]
WHERE [Extent1].[IsTerminated] = 0
Part 15 - Conditional Mapping in entity framework with code first
In Part 14, we discussed Conditional Mapping in entity framework with database first
approach. Please watch Part 14 before proceeding. In this video we will discussConditional
Mapping in entity framework with code first approach.
Step 1: Create a new empty asp.net web application project. Name it Demo. Install entity
framework if it's not already installed.
56 | P a g e
Step 2: Add a class file to the project. Name it Employee.cs. Copy and paste the following
code.
namespace Demo
{
public class Employee
{
public int EmployeeID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Gender { get; set; }
public bool IsTerminated { get; set; }
}
}
Step 3: Add a class file to the project. Name it EmployeeDBContext.cs. Copy and paste the
following code.
using System.Data.Entity;
namespace Demo
{
public class EmployeeDBContext : DbContext
{
public DbSet<Employee> Employees { get; set; }
base.OnModelCreating(modelBuilder);
}
}
}
Step 5: Add a webform to the project. Drag and drop a GridView control.
Step 6: Copy and paste the following code in the code-behind file.
protected void Page_Load(object sender, EventArgs e)
{
EmployeeDBContext employeeDBContext = new EmployeeDBContext();
GridView1.DataSource = employeeDBContext.Employees.ToList();
GridView1.DataBind();
57 | P a g e
}
Step 7: If you already have Sample database in SQL Server. Delete it from SQL Server
Management Studio.
Step 8: Run the application. Sample database and Employees table must be created at this
point.
Step 10: Open SQL profiler and run the webform. Notice that the select query has
aWHERE clause, which will always return employees who are not terminated.
SELECT
[Extent1].[EmployeeID] AS [EmployeeID],
[Extent1].[FirstName] AS [FirstName],
[Extent1].[LastName] AS [LastName],
[Extent1].[Gender] AS [Gender]
FROM [dbo].[Employees] AS [Extent1]
WHERE [Extent1].[IsTerminated] = 0
Part 16 - Self referencing association in entity framework
In this video, we will discuss self referencing association in entity framework with database
first approach. Let us understand self-referencing association with an example.
We will be using the following Employees table in this demo. This table is a self-
referencing table because to get the manager of an employee, we take ManagerIdcolumn
value and look up in the EmployeeId column of the same table.
58 | P a g e
SQL script to create the table
Create table Employees
(
EmployeeID int primary key identity,
EmployeeName nvarchar(50),
ManagerID int foreign key references Employees(EmployeeID)
)
GO
Now if you generate an ADO.NET entity data model based on this Employees table, the
following Employee entity is generated. Notice that a self-referencing association and 2
navigation properties (Employees1 & Employee1) are automatically created.
Right click on Employees1 navigation property and select properties. In the properties window
notice that the Multiplicity is set to Many. So, this navigation property returns employees who
are subordinates.
59 | P a g e
Similarly, right click on Employee1 navigation property and select properties. In the properties
window notice that the Multiplicity is set to Zero or One. So, this navigation property returns
the manager of an employee.
From a developer perspective the default navigation property names that entity framework
generates are not meaningful. If you have to write any code based on these navigation
properties, it can get even more complicated.
For example, let us say we want to display Employee names and their respective manager
names as shown below.
60 | P a g e
To achieve this we would drag and drop a GridView control on the web form and write the
following code in the code-behind file Page_Load event. Notice that, because of the poor
naming of the navigation properties the code is hard to read and maintain.
protected void Page_Load(object sender, EventArgs e)
{
EmployeeDBContext employeeDBContext = new EmployeeDBContext();
GridView1.DataSource = employeeDBContext.Employees.Select(emp => new
{
EmployeeName = emp.EmployeeName,
ManagerName = emp.Employee1 == null ? "Super Boss"
: emp.Employee1.EmployeeName
}).ToList();
GridView1.DataBind();
}
61 | P a g e
Now the code in the code-behind file would change as shown below which is more readable
and maintainable.
protected void Page_Load(object sender, EventArgs e)
{
EmployeeDBContext employeeDBContext = new EmployeeDBContext();
GridView1.DataSource = employeeDBContext.Employees.Select(emp => new
{
EmployeeName = emp.EmployeeName,
ManagerName = emp.Manager == null ? "Super Boss"
: emp.Manager.EmployeeName
}).ToList();
GridView1.DataBind();
}
Part 17 - Self referencing association in entity framework with code first
In this video, we will discuss self referencing association in entity framework with code
first approach. This is continuation to Part 16, where we discussed self-referencing association
with database first approach. Please watch Part 16 before proceeding.
Step 1: Create a new empty asp.net web application project. Name it Demo. Install entity
framework if it's not already installed.
Step 2: Add a class file to the project. Name it Employee.cs. Copy and paste the following
code.
namespace Demo
{
public class Employee
{
// Scalar properties
public int EmployeeID { get; set; }
public string EmployeeName { get; set; }
public int? ManagerID { get; set; }
// Navigation property
public Employee Manager { get; set; }
}
}
Step 3: Add a class file to the project. Name it EmployeeDBContext.cs. Copy and paste the
following code.
using System.Data.Entity;
namespace Demo
{
public class EmployeeDBContext : DbContext
{
public DbSet<Employee> Employees { get; set; }
62 | P a g e
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Employee>()
.HasOptional(e => e.Manager)
.WithMany()
.HasForeignKey(m => m.ManagerID);
base.OnModelCreating(modelBuilder);
}
}
}
Step 5: Add a webform to the project. Drag and drop a GridView control.
Step 6: Copy and paste the following code in the code-behind file.
using System;
using System.Linq;
namespace Demo
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
EmployeeDBContext employeeDBContext = new EmployeeDBContext();
GridView1.DataSource = employeeDBContext.Employees.Select(emp => new
{
EmployeeName = emp.EmployeeName,
ManagerName = emp.Manager == null ?
"Super Boss" : emp.Manager.EmployeeName
}).ToList();
GridView1.DataBind();
}
}
}
Step 7: If you already have Sample database in SQL Server. Delete it from SQL Server
Management Studio.
Step 8: Run the application. Sample database and Employees table must be created at this
point. Notice that EmployeeID is marked as primary key and ManagerID is marked as foreign
key.
63 | P a g e
Step 9: Insert test data using the following SQL script
Insert into Employees values ('John', NULL)
Insert into Employees values ('Mark', NULL)
Insert into Employees values ('Steve', NULL)
Insert into Employees values ('Tom', NULL)
Insert into Employees values ('Lara', NULL)
Insert into Employees values ('Simon', NULL)
Insert into Employees values ('David', NULL)
Insert into Employees values ('Ben', NULL)
Insert into Employees values ('Stacy', NULL)
Insert into Employees values ('Sam', NULL)
GO
Step 10: Reload web form and notice that the employee name and their respective manager
name is is displayed as expected.
Part 18 - Table Per Hierarchy (TPH) inheritance in entity framework
In this video, we will discuss implementing Table Per Hierarchy (TPH) inheritance in entity
framework with database first approach. In TPH inheritance one database table is used to
store data for all of the entity types in the inheritance hierarchy. Let us understand this with an
example.
64 | P a g e
SQL Script to create Employees Table
Create Table Employees
(
ID int primary key identity,
FirstName nvarchar(50),
LastName nvarchar(50),
Gender nvarchar(50),
AnuualSalary int,
HourlyPay int,
HoursWorked int,
Discriminator nvarchar(50)
)
Now if we generate an ADO.NET entity data model based on this Employees table, by default
the following Employee entity class is generated.
65 | P a g e
But from an application perspective we want 3 entity classes
Employee - This should be an abstract class and should contain all the common properties of
permanent and contract employees. ID, FirstName, LastName & Gender properties should be
present in this class.
PermanentEmployee - This class should inherit from the abstract Employee class and should
contain AnnualSalary property
ContractEmployee - This class should inherit from the abstract Employee class and should
contain HourlyPay & HoursWorked properties
66 | P a g e
2. Cut AnnualSalary property from Employee entity and paste it in Permanent
Employee entity.
3. Right click on the designer surface and select Add - Entity option, and provide the details as
shown below and click OK.
67 | P a g e
4. Cut HourlyPay & HoursWorked properties from Employee entity and paste then inContract
Employee entity. At this point, we should have the following 3 entities.
68 | P a g e
5. Right click on PermanentEmployee and select Table Mapping option, and
mapPermanentEmployee entity to Employees table. Also notice the conditional mapping,in
which we are using Discriminator column to determine when an Employee can
bePermanentEmployee.
6. Along the same lines, right click on ContractEmployee and select Table Mappingoption,
and map ContractEmployee entity to Employees table. Also notice theconditional mapping,
in which we are using Discriminator column to determine when an Employee can
be ContractEmployee.
69 | P a g e
7. Since we are using Discriminator column in conditional mapping we cannot use it again
with property mapping in Employee entity. So delete it from there.
8. Finally right click on Employee entity and select properties. In the properties window
set Abstract=true. This should make Employee class an abstract class.
Now, let us see how to query the data. Design a webform as shown below.
namespace Demo
70 | P a g e
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void RadioButtonList1_SelectedIndexChanged(object sender, EventArgs e)
{
EmployeeDBContext employeeDBContext = new EmployeeDBContext();
switch (RadioButtonList1.SelectedValue)
{
case "Permanent":
GridView1.DataSource = employeeDBContext.Employees
.OfType<PermanentEmployee>().ToList();
GridView1.DataBind();
break;
case "Contract":
GridView1.DataSource = employeeDBContext.Employees
.OfType<ContractEmployee>().ToList();
GridView1.DataBind();
break;
default:
GridView1.DataSource = ConvertEmployeesForDisplay(
employeeDBContext.Employees.ToList());
GridView1.DataBind();
break;
}
}
if (employee is PermanentEmployee)
{
71 | P a g e
dr["AnuualSalary"] = ((PermanentEmployee)employee).AnuualSalary;
dr["Type"] = "Permanent";
}
else
{
dr["HourlyPay"] = ((ContractEmployee)employee).HourlyPay;
dr["HoursWorked"] = ((ContractEmployee)employee).HoursWorked;
dr["Type"] = "Contract";
}
dt.Rows.Add(dr);
}
return dt;
}
}
}
Run the application and turn on the SQL profiler to inspect the queries that are generated.
72 | P a g e
[Extent1].[HourlyPay] AS [HourlyPay]
FROM [dbo].[Employees] AS [Extent1]
WHERE [Extent1].[Discriminator] = N'ContractEmployee'
Part 19 - Table Per Hierarchy (TPH) inheritance in entity framework with code
first
In this video, we will discuss implementing Table Per Hierarchy (TPH) inheritance in entity
framework with code first approach. This is continuation to Part 18, where we discussed
implementing Table Per Hierarchy inheritance with database first approach. Please watch Part
18 before proceeding.
In TPH inheritance one database table is used to store data for all of the entity types in the
inheritance hierarchy.
Step 1: Create a new empty asp.net web application project. Name it Demo. Install entity
framework if it's not already installed.
Step 2: Add a class file to the project. Name it Employee.cs. Copy and paste the following
code.
73 | P a g e
using System.ComponentModel.DataAnnotations.Schema;
namespace Demo
{
public abstract class Employee
{
[Column(Order = 1)]
public int ID { get; set; }
[Column(Order = 2)]
public string FirstName { get; set; }
[Column(Order = 3)]
public string LastName { get; set; }
[Column(Order = 4)]
public string Gender { get; set; }
}
}
Step 3: Add a class file to the project. Name it PermanentEmployee.cs. Copy and paste the
following code.
using System.ComponentModel.DataAnnotations.Schema;
namespace Demo
{
public class PermanentEmployee : Employee
{
[Column(Order = 5)]
public int AnnualSalary { get; set; }
}
}
Step 4: Add a class file to the project. Name it ContractEmployee.cs. Copy and paste the
following code.
using System.ComponentModel.DataAnnotations.Schema;
namespace Demo
{
public class ContractEmployee : Employee
{
[Column(Order = 6)]
public int HoursWorked { get; set; }
[Column(Order = 7)]
public int HourlyPay { get; set; }
}
}
Step 5: Add a class file to the project. Name it EmployeeDBContext.cs. Copy and paste the
following code.
using System.Data.Entity;
namespace Demo
{
public class EmployeeDBContext : DbContext
{
public DbSet<Employee> Employees { get; set; }
}
74 | P a g e
}
Step 7: Add a webform to the project. Copy and paste the following HTML.
<div style="font-family: Arial">
<asp:RadioButtonList ID="RadioButtonList1" runat="server" AutoPostBack="True"
onselectedindexchanged="RadioButtonList1_SelectedIndexChanged">
<asp:ListItem Text="Load all Employees" Value="All"></asp:ListItem>
<asp:ListItem Text="Load Permanent Employees" Value="Permanent"></asp:ListItem>
<asp:ListItem Text="Load Contract Employees" Value="Contract"></asp:ListItem>
</asp:RadioButtonList>
<asp:GridView ID="GridView1" runat="server">
</asp:GridView>
<br />
<asp:Button ID="btnAddPermanentEmployee" runat="server"
Text="Add Permanent Employee" onclick="btnAddPermanentEmployee_Click" />
<br />
<br />
<asp:Button ID="btnAddContractEmployee" runat="server"
Text="Add Contract Employee" onclick="btnAddContractEmployee_Click" />
</div>
Step 8: Copy and paste the following code in the code-behind file.
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
namespace Demo
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void RadioButtonList1_SelectedIndexChanged(object sender, EventArgs e)
{
EmployeeDBContext employeeDBContext = new EmployeeDBContext();
switch (RadioButtonList1.SelectedValue)
{
case "Permanent":
GridView1.DataSource =
employeeDBContext.Employees.OfType<PermanentEmployee>().ToList();
GridView1.DataBind();
break;
case "Contract":
75 | P a g e
GridView1.DataSource =
employeeDBContext.Employees.OfType<ContractEmployee>().ToList();
GridView1.DataBind();
break;
default:
GridView1.DataSource =
ConvertEmployeesForDisplay(employeeDBContext.Employees.ToList());
GridView1.DataBind();
break;
}
}
if (employee is PermanentEmployee)
{
dr["AnuualSalary"] = ((PermanentEmployee)employee).AnnualSalary;
dr["Type"] = "Permanent";
}
else
{
dr["HourlyPay"] = ((ContractEmployee)employee).HourlyPay;
dr["HoursWorked"] = ((ContractEmployee)employee).HoursWorked;
dr["Type"] = "Contract";
}
dt.Rows.Add(dr);
}
return dt;
}
76 | P a g e
{
PermanentEmployee permanentEmployee = new PermanentEmployee
{
FirstName = "Mike",
LastName = "Brown",
Gender = "Male",
AnnualSalary = 70000,
};
Step 7: If you already have Sample database in SQL Server. Delete it from SQL Server
Management Studio.
Step 8: Run the application. Sample database and Employees table must be created at this
point.
77 | P a g e
Insert into Employees values
('John', 'Stanmore', 'Male', 80000, NULL, NULL, 'PermanentEmployee')
Step 10: Reload the webform. Open SQL Profiler. Select the different radio buttons to load
contract, permanent & all employees and notice the queries generated by the entity framework.
Also click on the following buttons.
a) Add Permanent Employee
b) Add Contract Employee
Notice that the Discriminator column is populated automatically based on the type of
Employee being inserted.
Part 20 - Table Per Type (TPT) inheritance in entity framework
In this video we will discuss implementing Table Per Type (TPT) inheritance in entity
framework with database first approach. In TPT inheritance one database table per type is used
to store data for the respective entity types in the inheritance hierarchy. This means there is no
problem of de-normalized tables.
In Parts 18 and 19 of Entity Framework tutorial we discussed how inheritance hierarchy can be
represented using Table Per Hierarchy (TPH). With TPH one database table is used to store
data of all the entity types in the inheritance hierarchy. The downside of this is that we have a
denormalized table and some columns will have NULL values depending on the type of the
derived object being saved to the database table.
78 | P a g e
The data of all the entity types in the above inheritance hierarchy is stored in the following
Employees table
The problem with TPH is that when we store a PermanentEmployee object to this table,
HoursWorked & HourlyPay columns will be left NULL. Along the same lines, when we store a
ContractEmployee object, AnnualSalary column will be NULL. With Table Per Type inheritance
we don't have this problem.
We will be using the followin 3 tables to implement Table Per Type (TPT) inheritance. Notice
that EmployeeID is the primary key of Employees table.
InPermanentEmployees & ContractEmployees, EmployeeID is the foreign key.
79 | P a g e
SQL Script to create the above 3 tables
Create Table Employees
(
EmployeeID int primary key,
FirstName nvarchar(50),
LastName nvarchar(50),
Gender nvarchar(50),
)
GO
Now if we generate an ADO.NET entity data model based on the above 3 tables, the following 3
entities are generated with an association instead of inheritance relation between the entities.
80 | P a g e
Delete the association between Employee and PermanentEmployee entities. This will also
automatically delete the PermanentEmployee navigation property from Employeeentity
and Employee navigation property from PermanentEmployee entity.
Now, add the inheritance relationship between Employee & ContractEmployee entities
1. Right click on the designer surface and select Add - Inheritance option
2. Select Employee as the Base Entity and ContractEmployee as the Derived entity
81 | P a g e
Along the same line, add the inheritance relationship
between Employee &PermanentEmployee entities
1. Right click on the designer surface and select Add - Inheritance option
2. Select Employee as the Base Entity and PermanentEmployee as the Derived entity
82 | P a g e
Now, let us see how to query the data. Design a webform as shown below.
83 | P a g e
</asp:GridView>
</div>
namespace Demo
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void RadioButtonList1_SelectedIndexChanged(object sender, EventArgs e)
{
EmployeeDBContext employeeDBContext = new EmployeeDBContext();
switch (RadioButtonList1.SelectedValue)
{
case "Permanent":
GridView1.DataSource = employeeDBContext.Employees
.OfType<PermanentEmployee>().ToList();
GridView1.DataBind();
break;
case "Contract":
GridView1.DataSource = employeeDBContext.Employees
.OfType<ContractEmployee>().ToList();
GridView1.DataBind();
break;
default:
GridView1.DataSource =
ConvertEmployeesForDisplay(employeeDBContext.Employees.ToList());
GridView1.DataBind();
break;
}
}
84 | P a g e
foreach (Employee employee in employees)
{
DataRow dr = dt.NewRow();
dr["ID"] = employee.EmployeeID;
dr["FirstName"] = employee.FirstName;
dr["LastName"] = employee.LastName;
dr["Gender"] = employee.Gender;
if (employee is PermanentEmployee)
{
dr["AnuualSalary"] = ((PermanentEmployee)employee).AnnualSalary;
dr["Type"] = "Permanent";
}
else
{
dr["HourlyPay"] = ((ContractEmployee)employee).HourlyPay;
dr["HoursWorked"] = ((ContractEmployee)employee).HoursWorked;
dr["Type"] = "Contract";
}
dt.Rows.Add(dr);
}
return dt;
}
}
}
Run the application and turn on the SQL profiler to inspect the queries that are generated.
Part 21 - Table Per Type (TPT) inheritance in entity framework code first
In this video, we will discuss implementing Table Per Type (TPT) inheritance in entity
framework with code first approach. This is continuation to Part 20, where we discussed
implementing Table Per Type inheritance with database first approach. Please watch Part
20 before proceeding.
In TPT inheritance one database table per type is used to store data for the respective entity
types in the inheritance hierarchy.
Step 1: Create a new empty asp.net web application project. Name it Demo. Install entity
framework if it's not already installed.
Step 2: Add a class file to the project. Name it Employee.cs. Copy and paste the following code.
using System.ComponentModel.DataAnnotations.Schema;
namespace Demo
{
[Table("Employees")]
public class Employee
{
85 | P a g e
public int EmployeeID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Gender { get; set; }
}
Step 3: Add a class file to the project. Name it PermanentEmployee.cs. Copy and paste the
following code.
using System.ComponentModel.DataAnnotations.Schema;
namespace Demo
{
[Table("PermanentEmployees")]
public class PermanentEmployee : Employee
{
public int AnnualSalary { get; set; }
}
}
Step 4: Add a class file to the project. Name it ContractEmployee.cs. Copy and paste the
following code.
using System.ComponentModel.DataAnnotations.Schema;
namespace Demo
{
[Table("ContractEmployees")]
public class ContractEmployee : Employee
{
public int HoursWorked { get; set; }
public int HourlyPay { get; set; }
}
}
Step 5: Add a class file to the project. Name it EmployeeDBContext.cs. Copy and paste the
following code.
using System.Data.Entity;
namespace Demo
{
public class EmployeeDBContext : DbContext
{
public DbSet<Employee> Employees { get; set; }
}
}
86 | P a g e
Step 7: Add a webform to the project. Copy and paste the following HTML.
<div style="font-family: Arial">
<asp:RadioButtonList ID="RadioButtonList1" runat="server" AutoPostBack="True"
OnSelectedIndexChanged="RadioButtonList1_SelectedIndexChanged">
<asp:ListItem Text="Load all Employees" Value="All"></asp:ListItem>
<asp:ListItem Text="Load Permanent Employees" Value="Permanent"></asp:ListItem>
<asp:ListItem Text="Load Contract Employees" Value="Contract"></asp:ListItem>
</asp:RadioButtonList>
<asp:GridView ID="GridView1" runat="server">
</asp:GridView>
<br />
<asp:Button ID="btnAddPermanentEmployee" runat="server"
Text="Add Permanent Employee"
OnClick="btnAddPermanentEmployee_Click" />
<br />
<br />
<asp:Button ID="btnAddContractEmployee" runat="server" Text="Add Contract Employee"
OnClick="btnAddContractEmployee_Click" />
</div>
Step 8: Copy and paste the following code in the code-behind file.
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
namespace Demo
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void RadioButtonList1_SelectedIndexChanged(object sender, EventArgs e)
{
EmployeeDBContext employeeDBContext = new EmployeeDBContext();
switch (RadioButtonList1.SelectedValue)
{
case "Permanent":
GridView1.DataSource = employeeDBContext.Employees
.OfType<PermanentEmployee>().ToList();
GridView1.DataBind();
break;
case "Contract":
GridView1.DataSource = employeeDBContext.Employees
.OfType<ContractEmployee>().ToList();
GridView1.DataBind();
break;
default:
87 | P a g e
GridView1.DataSource =
ConvertEmployeesForDisplay(employeeDBContext.Employees.ToList());
GridView1.DataBind();
break;
}
}
if (employee is PermanentEmployee)
{
dr["AnuualSalary"] = ((PermanentEmployee)employee).AnnualSalary;
dr["Type"] = "Permanent";
}
else
{
dr["HourlyPay"] = ((ContractEmployee)employee).HourlyPay;
dr["HoursWorked"] = ((ContractEmployee)employee).HoursWorked;
dr["Type"] = "Contract";
}
dt.Rows.Add(dr);
}
return dt;
}
88 | P a g e
AnnualSalary = 70000,
};
Step 7: If you already have Sample database in SQL Server. Delete it from SQL Server
Management Studio.
Step 8: Run the application. Sample database and the required tables (Employees,
PermanentEmployees & ContractEmployees) must be created at this point.
89 | P a g e
Insert into ContractEmployees values (2, 50, 160)
Insert into ContractEmployees values (5, 40, 120)
Insert into ContractEmployees values (6, 30, 140)
GO
Step 10: Reload the webform. Open SQL Profiler. Select the different radio buttons to load
contract, permanent & all employees and notice the queries generated by the entity framework.
Also click on the following buttons.
a) Add Permanent Employee
b) Add Contract Employee
Notice that entity framework automatically inserts records into the correct underlying tables
based on the type of Employee (PermanentEmployee or ContractEmployee) being inserted.
Note: You can also use Fluent API to do the table mapping by overriding OnModelCreating() as
shown below.
public class EmployeeDBContext : DbContext
{
public DbSet<Employee> Employees { get; set; }
base.OnModelCreating(modelBuilder);
}
}
Part 22 - Many to many relationship in entity framework
In this video we will discuss many-to-many relationship in entity framework with database
first approach. We will be using the following 3 tables in this demo. There is aMany-to-
Many relationship between Courses and Students. A student can enroll into many courses and
a single course can have many students enrolled. The data is stored in
the StudentCourses bridge table
90 | P a g e
SQL Script to create the above 3 tables
Create Table Courses
(
CourseID int identity primary key,
CourseName nvarchar(50)
)
GO
Now if we generate an ADO.NET entity data model based on the above 3 tables, only 2
entities (Student & Course) are generated with a Many-to-Many association between
them. Notice that an entity for the bridge table (StudentCourses) is not generated in the entity
model. Also, notice that we have navigation properties to navigate from Course to Students and
from Student to Courses.
At this point, right click on Many-to-Many association and select Table Mapping option. In
the Mapping Details window notice that, the StudentCourses Many-to-Many association is
mapped to StudentCourses database table.
Now, let us see how to query the data. We want to display all the students names and the
courses they have opted into.
92 | P a g e
Drag and drop a GridView control on the webform. Copy and paste the following code in the
code-behind file.
protected void Page_Load(object sender, EventArgs e)
{
EmployeeDBContext employeeDBContext = new EmployeeDBContext();
Turn on SQL Profiler and load the webform. Notice that the generated SQL Query joins all the
3 tables (Students, Courses & StudentCourses)
SELECT
[Extent1].[StudentID] AS [StudentID],
[Extent1].[StudentName] AS [StudentName],
[Join1].[CourseName] AS [CourseName]
FROM [dbo].[Students] AS [Extent1]
INNER JOIN (SELECT [Extent2].[StudentID] AS [StudentID],
[Extent3].[CourseName] AS [CourseName]
FROM [dbo].[StudentCourses] AS [Extent2]
INNER JOIN [dbo].[Courses] AS [Extent3]
ON [Extent3].[CourseID] = [Extent2].[CourseID] )
AS [Join1] ON [Extent1].[StudentID] = [Join1].[StudentID]
Modifying data:
Assign Mike to WCF course
Remove John from SQL Server course
To achieve this,
1. Drag and Drop 2 button controls on the web form
2. Change text on the
First button to Assign WCF Course to Mike
93 | P a g e
Second button to Remove John from SQL Server Course
3. Copy and paste the following code in the respective click event handler methods
protected void Button1_Click(object sender, EventArgs e)
{
EmployeeDBContext employeeDBContext = new EmployeeDBContext();
Course WCFCourse = employeeDBContext.Courses
.FirstOrDefault(x => x.CourseID == 4);
Turn on SQL Profiler and load the webform. Click on the buttons and notice the queries
generated.
Based on Course & Student classes, entity framework should generate the required database
tables with many-to-many relationship
94 | P a g e
Step 1: Create a new empty asp.net web application project. Name it Demo. Install entity
framework if it's not already installed.
Step 2: Add a class file to the project. Name it Course.cs. Copy and paste the following code.
using System.Collections.Generic;
namespace Demo
{
95 | P a g e
public class Course
{
public int CourseID { get; set; }
public string CourseName { get; set; }
public IList<Student> Students { get; set; }
}
}
Step 3: Add a class file to the project. Name it Student.cs. Copy and paste the following code.
using System.Collections.Generic;
namespace Demo
{
public class Student
{
public int StudentID { get; set; }
public string StudentName { get; set; }
public IList<Course> Courses { get; set; }
}
}
Step 4: Add a class file to the project. Name it EmployeeDBContext.cs. Copy and paste the
following code.
using System.Data.Entity;
namespace Demo
{
public class EmployeeDBContext : DbContext
{
public DbSet<Course> Courses { get; set; }
public DbSet<Student> Students { get; set; }
base.OnModelCreating(modelBuilder);
}
}
}
96 | P a g e
providerName="System.Data.SqlClient" />
</connectionStrings>
Step 6: Add a webform to the project. Copy and paste the following HTML.
<div style="font-family: Arial">
<asp:GridView ID="GridView1" runat="server">
</asp:GridView>
<br />
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click"
Text="Assign WCF Course to Mike"/>
<br />
<br />
<asp:Button ID="Button2" runat="server" OnClick="Button2_Click"
Text="Remove John from SQL Server Course"/>
</div>
Step 7: Copy and paste the following code in the code-behind file.
using System;
using System.Linq;
namespace Demo
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
EmployeeDBContext employeeDBContext = new EmployeeDBContext();
GridView1.DataBind();
}
employeeDBContext.Students.Include("Courses")
.FirstOrDefault(x => x.StudentID == 1).Courses.Add(WCFCourse);
employeeDBContext.SaveChanges();
}
97 | P a g e
protected void Button2_Click(object sender, EventArgs e)
{
EmployeeDBContext employeeDBContext = new EmployeeDBContext();
employeeDBContext.Students.Include("Courses")
.FirstOrDefault(x => x.StudentID == 2).Courses.Remove(SQLServerCourse);
employeeDBContext.SaveChanges();
}
}
}
Step 8: If you already have Sample database in SQL Server. Delete it from SQL Server
Management Studio.
Step 9: Run the application. Sample database and the required tables (Courses, Students &
StudentCourses) must be created at this point.
Step 10: Insert test data using the following SQL script
-- Insert into Courses Table
Insert into Courses values ('C#')
Insert into Courses values ('ASP.NET')
Insert into Courses values ('SQL Server')
Insert into Courses values ('WCF')
GO
Step 11: Reload the webform. Notice that the data is displayed as expected. Now, click on the
following buttons, and notice that StudentCourses table is updated as expected.
a) Assign WCF Course to Mike
b) Remove John from SQL Server Course
Part 24 - Entity for BridgeTable in many to many relationship
In this video we will discuss a scenario in which Entity framework generates an Entity for
the many-to-many relationship bridge table.
98 | P a g e
In Part 22 we used the following 3 tables. Notice that the Bridge Table (StudentCourses) does
not have any additional columns except for the foreign keys (StudentID & CourseID). When an
entity model was created based on these 3 tables, an entity for the bridge table is not created.
Let us now, modify the Bridge Table (StudentCourses) to include EnrolledDate column.
99 | P a g e
SQL Script to create all the 3 tables (Courses, Students & StudentCourses)
Create Table Courses
(
CourseID int identity primary key,
CourseName nvarchar(50)
)
GO
100 | P a g e
Insert into Courses values ('C#')
Insert into Courses values ('ASP.NET')
Insert into Courses values ('SQL Server')
Insert into Courses values ('WCF')
GO
Now if we generate an ADO.NET entity data model based on the above 3 tables, notice that 3
entities (Student, Course & StudentCourse) are generated. An entity (StudentCourse) for the
bridge table (StudentCourses) is also generated.
a) Student entity has One-Many relationship with StudentCourse Entity
b) Course entity has One-Many relationship with StudentCourse Entity
Entity Framework interview question : Explain when an entity will and will not be created
by the entity framework for the bridge table in a many-to-many relationship?
An entity for the bridge table is NOT created when the bridge table has only the foreign keys.
On the other if the bridge table has any other columns apart from the foreign key columns then
a bridge table is created.
Querying data: We want to display students and courses data in a GridView as shown below.
To achieve this
1. Drag and drop a GridView & 2 Button controls on the webform
2. Change the Text on Button1 control to "Assign WCF Course to Mike" and double click on
the button control to generate the click event handler
3. Change the Text on Button2 control to "Remove John from SQL Server Course"and
double click on the button control to generate the click event handler
101 | P a g e
4. At this point the webform design should look as shown below
GridView1.DataBind();
}
102 | P a g e
{
EmployeeDBContext employeeDBContext = new EmployeeDBContext();
employeeDBContext.StudentCourses.AddObject
(new StudentCourse { StudentID = 1, CourseID = 4,
EnrolledDate = DateTime.Now });
employeeDBContext.SaveChanges();
}
Run the application. Notice that the data is displayed as expected. Now, click on the following
buttons, and notice that StudentCourses table is updated as expected.
a) Assign WCF Course to Mike
b) Remove John from SQL Server Course
Part 25 - Entity for BridgeTable in many to many relationship code first
In this video we will discuss creating an Entity for the bridge table in a many-to-many
relationship with code first. This is continuation to Part 24. Please watch Part 24 before
proceeding.
103 | P a g e
1. Courses - CourseID should be the Primary Key
2. Students - StudentID should be the Primary Key
3. StudentCourses - Composite primary key consisting of CourseID & StudentIDcolumns.
CourseID should also be the foreign key referencing CourseID column in Courses table.
StudentID should also be the foreign key referencing StudentID column in Students table.
To achieve this
Step 1: Create a new empty asp.net web application project. Name it Demo. Install entity
framework if it's not already installed.
Step 2: Add a class file to the project. Name it Course.cs. Copy and paste the following code.
using System.Collections.Generic;
namespace Demo
{
public class Course
{
public int CourseID { get; set; }
public string CourseName { get; set; }
public IList<StudentCourse> StudentCourses { get; set; }
}
}
Step 3: Add a class file to the project. Name it Student.cs. Copy and paste the following code.
using System.Collections.Generic;
namespace Demo
104 | P a g e
{
public class Student
{
public int StudentID { get; set; }
public string StudentName { get; set; }
public IList<StudentCourse> StudentCourses { get; set; }
}
}
Step 4: Add a class file to the project. Name it StudentCourse.cs. Copy and paste the
following code.
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Demo
{
public class StudentCourse
{
public Course Course { get; set; }
Step 5: Add a class file to the project. Name it EmployeeDBContext.cs. Copy and paste the
following code.
using System.Data.Entity;
namespace Demo
{
public class EmployeeDBContext : DbContext
{
public DbSet<Course> Courses { get; set; }
public DbSet<Student> Students { get; set; }
public DbSet<StudentCourse> StudentCourses { get; set; }
}
}
105 | P a g e
Step 7: Add a webform to the project. Copy and paste the following HTML.
<body>
<form id="form1" runat="server">
<div style="font-family: Arial">
<asp:GridView ID="GridView1" runat="server">
</asp:GridView>
<br />
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click"
Text="Assign WCF Course to Mike"/>
<br />
<br />
<asp:Button ID="Button2" runat="server" OnClick="Button2_Click"
Text="Remove John from SQL Server Course"/>
</div>
Step 8: Copy and paste the following code in the code-behind file.
using System;
using System.Linq;
namespace Demo
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
EmployeeDBContext employeeDBContext = new EmployeeDBContext();
GridView1.DataBind();
}
106 | P a g e
EmployeeDBContext employeeDBContext = new EmployeeDBContext();
employeeDBContext.StudentCourses.Add(new StudentCourse
{ StudentID = 1, CourseID = 4, EnrolledDate = DateTime.Now });
employeeDBContext.SaveChanges();
}
Step 9: If you already have Sample database in SQL Server. Delete it from SQL Server
Management Studio.
Step 10: Run the application. Sample database and the required tables (Courses, Students &
StudentCourses) must be created at this point.
Step 11: Insert test data using the following SQL script
-- Insert into Courses Table
Insert into Courses values ('C#')
Insert into Courses values ('ASP.NET')
Insert into Courses values ('SQL Server')
Insert into Courses values ('WCF')
GO
Step 12: Reload the webform. Notice that the data is displayed as expected. Now, click on the
following buttons, and notice that StudentCourses table is updated as expected.
a) Assign WCF Course to Mike
b) Remove John from SQL Server Course
107 | P a g e