You are on page 1of 48

Page | 1

What is Entity Framework?


First question that comes to the mind is what is an entity framework?
Microsoft has given following definition:
The Microsoft ADO.NET Entity Framework is an Object/Relational Mapping (ORM) framework that
enables developers to work with relational data as domain-specific objects, eliminating the need for
most of the data access plumbing code that developers usually need to write. Using the Entity
Framework, developers issue queries using LINQ, then retrieve and manipulate data as strongly typed
objects. The Entity Frameworks ORM implementation provides services like change tracking, identity
resolution, lazy loading, and query translation so that developers can focus on their applicationspecific business logic rather than the data access fundamentals.
To simply say it: Entity framework is an Object/Relational Mapping (O/RM) framework. It is an
enhancement to ADO.NET that gives developers an automated mechanism for accessing & storing the
data in the database and working with the results in addition to DataReader and DataSet.

Now the question is what is O/RM framework and why do we need it?
ORM is a tool for storing data from domain objects to relational database like MS SQL Server in an
automated way without much programming. O/RM includes three main parts: Domain class objects,
Relational database objects and Mapping information on how domain objects maps to relational database
objects (tables, views & storedprocedures). ORM helps us to keep our database design separate from our
domain class design. This makes application maintainable and extendable. It also automates standard
CRUD operation (Create, Read, Update & Delete) so developer doesnt need to write it manually.

For more info visit: http://en.wikipedia.org/wiki/Object-relational_mapping

There are many ORM frameworks for .net in the market like DataObjects.Net, NHibernate, OpenAccess,
SubSonic etc. Entity Framework is an open source ORM framework from Microsoft.

Entity Framework Architecture


Following figure shows the overall architecture of the Entity Framework. Lets see each component of the
architecture:

Page | 2

EDM (Entity Data Model): EDM consist three main parts- Conceptual model, Mapping and Storage
model.

Conceptual Model: Conceptual model is your model classes and their relationships. This will be
independent from your database table design.

Storage Model: Storage model is your database design model which includes tables, views, stored
procedures and their relationships and keys.

Mapping: Mapping consist information about how your conceptual model is mapped to storage model.

LINQ to Entities:LINQ to Entities is query language used to write queries against the object model. It
returns entities which are defined in the conceptual model. You can use your LINQ skills here.

Entity SQL:Entity SQL is again a query language same as LINQ to Entities. However it is little more
difficult than L2E and also developer need to learn it separately.

Page | 3
Object Service:Object service is a main entry point for accessing data from database and to return it
back. Object service is responsible for materialization which is process of converting data returned from
entity client data provider (next layer) to an entity object structure.

Entity Client Data Provider:The main responsibility of this layer is to convert L2E or Entity SQL
queries into SQL query which is understood by underlying database. It communicates with ADO.Net data
provider which in turn sends or retrieves data from database.

ADO.Net Data Provider:This layer communicates with database using standard ADO.Net.

Setup EntityFramework Environment:


Install the following for the basic tutorials:

.NET Framework 4.5/Visual Studio 2012

MS SQL Server 2005/2008/2012 Express

Setting up the database

This tutorial will use sample SchoolDB which has different tables, stored procedures and view.

Following is SchoolDB database design:

Page | 4

One-to-One: Student and StudentAddress has one-to-one relationship eg. Student


has zero or one StudentAddress.

One-to-Many: Standard and Teacher has one-to-many relationship eg. many


Teachers can be associate with one Standard.

Many-to-Many: Student and Course has many-to-many relationship using


StudentCourse table where StudentCourse table includes StudentId and CourseId. So
one student can join many courses and one course also can have many students.

Sample project contains SchoolDB.mdf which you can attach to your local SQL server 2005 database.

Create Entity Data Model in Entity


Framework 5.0

Page | 5
Here, we are going to create Entity Data Model (EDM) for SchoolDB database and understand basic
building blocks.

You can create entity data model for existing database in Entity Framework 5.0 the same way as you
created it in Entity Framework 4.1/4.3.

Lets do it step by step.

1. Open Visual Studio 2012 and create console project.

2. Now, add Entity Data Model by right clicking on the project in the solution explorer -> Add -> click
New Item and select ADO.NET Entity Data Model from popup, give Name School and click Add
button.

Page | 6

3. Entity Data Model Wizard in VS2012 opens with four options to select. EF Designer from database is
for database first approach, Empty EF Designer model for model first approach, Empty Code First
model and Code First from database is for code first approach. We will focus of database first approach
in the basic tutorials so select EF Designer from database option and click Next

Page | 7

4. You can choose from your existing DB Connections or create new connection by clicking New
Connection button. I use existing db connection to my SchoolDB Database. This will also add connection
string to your app.config file with default suffix with db name. You can change it if you want. Click
Next after you set up your db connection.

Page | 8

5. In this step, you need to choose the version of Entity Framework. We will use Entity Framework 5.0 in
the basic tutorials so select Entity Framework 5.0 and click Next.

Page | 9

6. This step will display all the Tables, Views and Stored Procedures in the database. Select tables, views
and SPs you want, keep the default checkboxes selected and click Finish. You can change Model
Namespace if you want.

Note:
Pluralize or singularize generated object names checkbox singularize entityset name if table name in
the database is plural eg. If SchoolDB has Students table name then entityset would be singular Student.
Similarly relationships between the model will be pluralize if table has one-to-many or many-to-many
relationship with other table. Eg. Student has many-to-many relationship with course table so Student
entity set will have plural property name 'Courses' for the collection of courses.

second checkbox, Include foreign key columns in the model includes foreign key property explicitly to
represent the foreign key. For example, Student table has one-to-many relationship with Standard table.
So every student is associated with only one standard. To represent this in the model, Student entityset
includes StandardId property with Standard navigation property. If this checkbox is unchecked then it will
only include Standard property but not StandardId in Student entityset.

Third checkbox, Import selected stored procedures and functions into entity model automatically
creates Function Imports for the stored procedures and functions. You dont need to manyally import it as
you had to do it prior to Entity Framework 5.0.

P a g e | 10

7. After clicking on Finish, it will add School.edmx file into your project.

Open EDM designer by double clicking on School.edmx that displays all the entities for selected tables
and relation between them as below:

P a g e | 11

So this way you can create simple EDM from your existing database.

Now lets see all the building blocks of generated EDM (School.edmx) as shown in above figure.

Entity-Table Mapping:

Each entity in EDM is mapped with database table. You can check entity-table mapping by right click on
any entity in the EDM designer -> select Table Mapping. Also, if you change any property name of entity
from designer then table mapping would reflect that automatically.

P a g e | 12

Context & Entity Classes:

Every Entity Data Model generates one context class and multiple entity classes for each DB table.
Expand School.edmx and see two important files, {EDM Name}.Context.tt and {EDM Name}.tt:

P a g e | 13

School.Context.tt: This T4 template file generates context class whenever you change Entity Data Model
(.edmx file). You can see context class file by expanding School.Context.tt. Context class resides in
{EDM Name}.context.cs file. Default context class name is {DB Name} + Entities eg. Context class
name for our SchoolDB is SchoolDBEntities. Context class is derived from DBContext class in Entity
Framework 5.0. Prior to EF 5.0, it used to derive from ObjectContext.

P a g e | 14

School.tt: School.tt is T4 template file that generates entity classes for each DB tables. Entity classes are
POCO (Plain Old CLR Object) classes that can be proxy classes (we will see later what is proxy classes).

EDM Designer: EDM designer represents your conceptual model. It consist Entities, associations &
multiplicity between the entities. Initially it will exactly look like your database table structure but you
can add or merge columns or remove columns which are not required by your application from this
designer. Even you can add new object in this model which can have columns from different database
tables from context menu as shown in above figure. Remember, whatever changes you do here it should
be mapped with storage model. So you have to be careful while doing any changes in the designer.

You can open this EDM designer in XML view where you can see all the three part of EDM- Conceptual
schema (CSDL), Storage schema (SSDL) and mapping schema (MSL), together in XML view.

P a g e | 15
Right click on School.edmx -> click Open with.., this will open popup. Select XML (text) Editor in the
popup. Visual Studio cannot display the model in Design view and in XML at the same time, so you will
see a message asking whether its OK to close the Design view of the model. Click Yes. This will open
XML view. You can see following XML view by toggling all outlining

You can see SSDL content, CSDL content and C-S mapping content here. If you expand SSDL and
CSDL, each one has some common XML node under each schema node. You dont need to edit xml
because you can do it in the Model Browser.

Model Browser: Open Model Browser by right clicking on the EDM Designer and select Model Browser
from context menu:

Model browser contains all the information about the EDM, its conceptual model, storage model and
mapping information.

P a g e | 16

EntityContainer EntityContainer is a wrapper for EntitySets and AssociationSets. It is critical entry point
for querying the model.

EntitySet: EntitySet is a container for EntityType. It is set of same entitytype. You can think it like db
table.

P a g e | 17
EntityType: EntityType is a datatype in the model. You can see each EntityType for your conceptual
model in XML. If you expand EntityType node in XML, you can see each properties and its type and
other info.

AssociationSet: AssociationSet defines the relation between each EntitySet.

Types of Entity in Entity Framework:


There was four types of Entities in Entity Framework 4.x, 1) EntityObject 2) POCO 3) POCO Proxy
(dnamic proxy) 4) Self-Tracking Entities.

Entity Framework 5.0 is limited to POCO entity and Dynamic proxy entity. EntityObject used to use with
ObjectContext which is not being used in Entity Framework 5.0. Also, it is not recommended to use selftracking entities.

POCO (Plain Old CLR Object): POCO class is the class that doesnt depends on any framework
specific base class. It is like any other normal .net class that is why it is called Plain Old CLR Objects.

These POCO entities (also known as persistence-ignorant objects) support most of the same query, insert,
update, and delete behaviors as entity types that are generated by the Entity Data Model. Eg. Following is
a Student POCO class.
public class Student
{
public int StudentID { get; set; }
public string StudentName{ get; set; }
public Standard Standard{ get ; set; }
public StudentAddress StudentAddress{ get ; set; }
public IList<Course> Courses{ get; set; }
}

Dynamic Proxy (POCO Proxy):

Dynamic Proxy is a runtime proxy class of POCO entity. POCO entity becomes POCO Proxy entity if it
meets the certain requirements to enable lazy loading and automatic change tracking. It adds some
methods at runtime to your POCO class which does instant change tracking and lazy loading stuff.

P a g e | 18

POCO entity should meet the following requirement to become POCO proxy:
1. A custom data class must be declared with public access.
2. A custom data class must not be sealed (NotInheritable in Visual Basic)
3. A custom data class must not be abstract (MustInherit in Visual Basic).
4. ProxyCreationEnabled option should not set to false (default is true) in context class
5. Each navigation property must be declared as public, virtual

Note: By default dynamic proxy is enabled for every entity. However, you can disable dynamic proxy by
setting ProxyCreationEnabled option to false in context class.
context.Configuration.ProxyCreationEnabled = false;

EDM generates POCO entities which satisfy above requirement of dynamic proxy by default.

Following is Student POCO class generated by EDM:


public partial class Student
{
public Student()
{
this.Courses = new HashSet<Course>();
}
public int StudentID { get; set; }
public string StudentName { get; set; }
public Nullable<int> StandardId { get; set; }
public Standard Standard { get; set; }
public StudentAddress StudentAddress { get; set; }
public virtual ICollection<Course> Courses { get; set; }
}

At runtime type of Student will be System.Data.Entity.DynamicProxies.Student as below:

P a g e | 19

Getting the actual entity type from a dynamic proxy:

You can use ObjectContext.GetObjectType() to find actual type of dynamic proxy as below:

Entity can have two types of properties, Scalar properties and Navigation properties.

Scalar properties are properties whose actual values are contained in the entity. For example, Student
entity has scalar properties e.g. StudentId, StudentName. These corresponds with the Student table
columns.

Navigation properties are pointers to other related entities. The Student has Standard property as
navigation property that will enable application to navigate from a Student to related Standard entity.

Querying with EDM:


You can query EDM mainly by three ways, 1) LINQ to Entities 2) Entity SQL 3) Native SQL

1) LINQ to Entities: L2E query syntax is easier to learn than Entity SQL. You can use your LINQ skills
for querying with EDM. There are two types of syntax you can use with LINQ-to-Entities, LINQ Method
Syntax with Lamda expression and LINQ query syntax.

LINQ Method syntax(lamda expression):

P a g e | 20
//Querying with LINQ to Entities
using (var context = new SchoolDBEntities())
{
var L2EQuery = context.Students.where(s => s.StudentName == Bill);
}

LINQ Query syntax:


using (var context = new SchoolDBEntities())
{
var L2EQuery = from st in context.Students
where st.StudentName == "Bill"
select st;
}

First, you have to create object of context class which is SchoolDBEntities. You should initialize it in
using() so that once it going out of using scope then it will automatically call Dispose() method of
DbContext. In both the syntax above, context returns IQueryable.

We will learn different types of LINQ to Entities query in projection query chapter later.

2) Entity SQL: Entity SQL is another way to create a query. It is processed by the Entity Frameworks
Object Services directly. It returns ObjectQuery instead of IQueryable.

You need ObjectContext to create query using Entity SQL.

Following code snippet shows same query result as L2E query above.
//Querying with Object Services and Entity SQL
string sqlString = "SELECT VALUE st FROM SchoolDBEntities.Students " +
"AS st WHERE st.StudentName == 'Bill'";
var objctx = (ctx as IObjectContextAdapter).ObjectContext;
ObjectQuery<Student> student = objctx.CreateQuery<Student>(sqlString);
Student newStudent = student.First<Student>();

You can also use EntityConnection and EntityCommand to execute Entity SQL as below:
using (var con = new EntityConnection("name=SchoolDBEntities"))
{
con.Open();
EntityCommand cmd = con.CreateCommand();
cmd.CommandText = "SELECT VALUE st FROM SchoolDBEntities.Students as st where
st.StudentName='Bill'";
Dictionary<int, string> dict = new Dictionary<int, string>();

P a g e | 21
using (EntityDataReader rdr =
cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.CloseConnection))
{
while (rdr.Read())
{
int a = rdr.GetInt32(0);
var b = rdr.GetString(1);
dict.Add(a, b);
}
}
}

EntityDataReader doesnt return ObjectQuery. It returns data in rows & columns.

Visit MSDN blog to learn Entity SQL.

3) Native SQL You can execute native SQL query for relational database as below:
using (var ctx = new SchoolDBEntities())
{
var studentName = ctx.Students.SqlQuery("Select studentid, studentname,
standardId from Student where studentname='Bill'").FirstOrDefault<Student>();
}

We will learn to execute raw sql query using DbContext later.

Code First development with Entity Framework


4.1
Visual Studio 2010 brought new approaches to modeling for Entity Framework 4.1.

1. Code First
2. Model First
3. Database first
Code First: In the Code First approach, you avoid working with visual model designer (EDMX)
completely. You write your POCO classes first and then create database from these POCO classes.
Developers who follow the path of Domain-Driven Design (DDD) principles prefer to begin by coding
their classes first and then generating the database required to persist their data.

Please visit EF Code-First Tutorial to learn code first in detail.

P a g e | 22

Model First development with Entity


Framework
Model First: In Model First approach, you create Entities, relationships, and inheritance hierarchies
directly on the design surface of EDMX. So in Model First approach, when you add ADO.NET Entity
Data Model, you should select Empty EF Designer model.

You can create entity, association and inheritance on empty designer using toolbox.

P a g e | 23

After creating required entities, associations and inheritance on design surface of the empty model, you
can use designers context menu option 'Generate database from model' to generate DDL script.

Select existing database connection from wizard and then it will display DDL for the entities.

P a g e | 24

So this is called Model First approach.

Database First development with Entity


Framework 4.0
We have already seen this approach in Create Entity Data Model where we created model and classes
from existing database. So when you generate EDMX from existing database then it is a Database First
approach.

P a g e | 25

Eager Loading:
Eager loading is the process whereby a query for one type of entity also loads related entities as part of
the query. Eager loading is achieved using Include method of IQueryable.

Below code snippet shows eager loading where Standard entity will also be loaded with Student entity
using Include method:

LINQ Query Syntax:


using (var context = new SchoolDBEntities())
{
var res = (from s in context.Students.Include("Standard")
where s.StudentName == "Student1"
select s).FirstOrDefault<Student>();
}

LINQ Method Syntax:


using (var ctx = new SchoolDBEntities())
{
stud = ctx.Students.Include(s => s.Standard)
.Where(s => s.StudentName ==
"Student1").FirstOrDefault<Student>();
//you can also pass entity name as a string "Standard"
// stud = ctx.Students.Include("Standard")
.Where(s => s.StudentName ==
"Student1").FirstOrDefault<Student>();
}

Above code will result in following SQL query:


SELECT TOP (1)
[Extent1].[StudentID] AS [StudentID],
[Extent1].[StudentName] AS [StudentName],
[Extent2].[StandardId] AS [StandardId],
[Extent2].[StandardName] AS [StandardName],
[Extent2].[Description] AS [Description]
FROM [dbo].[Student] AS [Extent1]
LEFT OUTER JOIN [dbo].[Standard] AS [Extent2] ON [Extent1].[StandardId] =
[Extent2].[StandardId]
WHERE 'Student1' = [Extent1].[StudentName]

Load multiple levels of related entities:

P a g e | 26
You can also eagerly load multiple levels of related entities. Below code snippet loads related Student,
Standard and Teachers:
using (var ctx = new SchoolDBEntities())
{
stud = ctx.Students.Where(s => s.StudentName == "Student1")
.Include(s => s.Standard.Teachers).FirstOrDefault<Student>();
}

Above code results in following SQL query:


SELECT [Project2].[StudentID] AS [StudentID],
[Project2].[StudentName] AS [StudentName],
[Project2].[StandardId] AS [StandardId],
[Project2].[StandardName] AS [StandardName],
[Project2].[Description] AS [Description],
[Project2].[C1] AS [C1],
[Project2].[TeacherId] AS [TeacherId],
[Project2].[TeacherName] AS [TeacherName],
[Project2].[StandardId1] AS [StandardId1]
FROM ( SELECT
[Limit1].[StudentID] AS [StudentID],
[Limit1].[StudentName] AS [StudentName],
[Limit1].[StandardId1] AS [StandardId],
[Limit1].[StandardName] AS [StandardName],
[Limit1].[Description] AS [Description],
[Project1].[TeacherId] AS [TeacherId],
[Project1].[TeacherName] AS [TeacherName],
[Project1].[StandardId] AS [StandardId1],
CASE WHEN ([Project1].[TeacherId] IS NULL) THEN CAST(NULL AS int) ELSE 1 END
AS [C1]
FROM
(SELECT TOP (1) [Extent1].[StudentID] AS [StudentID], [Extent1].
[StudentName] AS [StudentName], [Extent1].[StandardId] AS [StandardId2], [Extent2].
[StandardId] AS [StandardId1], [Extent2].[StandardName] AS [StandardName], [Extent2].
[Description] AS [Description]
FROM [dbo].[Student] AS [Extent1]
LEFT OUTER JOIN [dbo].[Standard] AS [Extent2] ON [Extent1].[StandardId] =
[Extent2].[StandardId]
WHERE 'updated student' = [Extent1].[StudentName] ) AS [Limit1]
LEFT OUTER JOIN (SELECT
[Extent3].[TeacherId] AS [TeacherId],
[Extent3].[TeacherName] AS [TeacherName],
[Extent3].[StandardId] AS [StandardId]
FROM [dbo].[Teacher] AS [Extent3]
WHERE [Extent3].[StandardId] IS NOT NULL ) AS [Project1] ON [Limit1].
[StandardId2] = [Project1].[StandardId]
) AS [Project2]
ORDER BY [Project2].[StudentID] ASC, [Project2].[StandardId] ASC, [Project2].[C1]
ASC

Lazy Loading:
One of the important functionality of Entity Framework is lazy loading. Lazy loading means delaying the
loading of related data until you specifically request it. For example, Student class contains
StudentAddress as complex property. So context first loads all the students from the database then it will
load address of particular student when we access StudentAddress property as below.

P a g e | 27
using (var ctx = new SchoolDBEntities())
{
ctx.Configuration.LazyLoadingEnabled = true;
//Loading students only
IList<Student> studList = ctx.Students.ToList<Student>();
Student std = studList[0];
//Loads Student address for particular Student only (seperate SQL query)
StudentAddress add = std.StudentAddress;
}

Above code will result in two SQL query. First, it will fetch all students:
SELECT
[Extent1].[StudentID] AS [StudentID],
[Extent1].[StudentName] AS [StudentName],
[Extent1].[StandardId] AS [StandardId]
FROM [dbo].[Student] AS [Extent1]

And then sends following query when we get the reference of StudentAddress:
exec sp_executesql N'SELECT
[Extent1].[StudentID] AS [StudentID],
[Extent1].[Address1] AS [Address1],
[Extent1].[Address2] AS [Address2],
[Extent1].[City] AS [City],
[Extent1].[State] AS [State]
FROM [dbo].[StudentAddress] AS [Extent1]
WHERE [Extent1].[StudentID] = @EntityKeyValue1',N'@EntityKeyValue1
int',@EntityKeyValue1=1

However, you can also turn off lazy loading for particular property or entire context. To turn off lazy
loading for particular property, do not make it virtual. To turn off lazy loading for all entities in the
context, set its configuration property to false:
public SchoolDBEntities(): base("name=SchoolDBEntities")
{
this.Configuration.LazyLoadingEnabled = false;
}

Rules for lazy loading:


1. context.Configuration.ProxyCreationEnabled should be true.
2. context.Configuration.LazyLoadingEnabled should be true.

P a g e | 28
3. Complex property should be defined as virtual. Context will not do lazy loading if the property is
not define as virtual.

Explicit Loading with DBContext


Even with lazy loading disabled it is still possible to lazily load related entities, but it must be done with
an explicit call. Use Load method of DBEntityEntry object.

Following code explicitly loads Standard of particular Student using Reference() method of
DbEntityEntry:
using (var context = new SchoolDBEntities())
{
//Disable Lazy loading
context.Configuration.LazyLoadingEnabled = false;
var student = (from s in context.Students
where s.StudentName == "Bill"
select s).FirstOrDefault<Student>();
context.Entry(student).Reference(s => s.Courses).Load();
}

If you run above code, you can see that first it loads student but not standard as below:

Load method get Standard entity as below:

P a g e | 29

Above code execute two different database queries. First query is to get Student and second query to get
standard.

Load collection:

Use collection method instead of Reference method to load collection navigation property. Following
example loads courses of student.
using (var context = new SchoolDBEntities())
{
context.Configuration.LazyLoadingEnabled = false;
var student = (from s in context.Students
where s.StudentName == "Bill"
select s).FirstOrDefault<Student>();
context.Entry(student).Collection(s => s.Courses).Load();
}

Note: The Load extension method works just like ToList except that it avoids the creation of the list
altogether.

P a g e | 30

DBContext:
As you have seen in previous chapter, EDM generates Context class and Entity classes. This context class
is derived from System.Data.Entity.DbContext class.

DbContext is a primary class that is responsible for interacting with data as object. It often referred to as
context. It does following activities:

Querying: It can be useful in querying the database. It converts database values into entity
objects and vica versa.

Change Tracking: It keeps track of changes occurred in the entities after it has been querying
from the database.

Persisting Data: It also perform Insert, update and delete operation to the database based on the
entity states.

Prior to EntityFramework 4.1, EDM used to generate context class that derived from ObjectContext class.
It was little tricky to work with ObjectContext. DbContext is conceptually similar to ObjectContext. It is
a wrapper around ObjectContext which is useful in all development models: Code First, Model First and
Database First.

DBContext API is easier to use than ObjectContext API for all common tasks. However, you can get
reference of ObjectContext from DBContext to use some of the features of ObjectContext by using
IObjectContextAdpter as below:
using (var ctx = new SchoolDBEntities())
{
var objectContext = (ctx as IObjectContextAdapter).ObjectContext;
//use objectContext now
}

See what are the important methods and properties of DbContext class in the next chapter.

DBContext Class
DBContext represents a combination of the Unit-Of-Work and Repository patterns and enables you to
query a database and group together changes that will then be written back to the store as a unit.

Followings are important methods of DBContext class.

P a g e | 31

Public Methods:
Method
Name

Return Type

Description

Example

Entry(Objec DBEntityEntry Gets a


Entry method returns DBEntityEntry object of
t)
DbEntityEntry passed entity object through which we can
object for the change its state, currentValues and
given entity
originalValues.
providing
access to
dbCtx.Entry(StudentEntity).State =
information
System.Data.EntityState.Modified;
about the
entity and the dbCtx.Entry(StudentEntity).CurrentValues.SetVal
ability to
ues(StudentEntityDTO);
perform actions
on the entity. dbCtx.Entry(StudentEntity).OriginalValues.SetVal
ues(StudentEntityDTO);
Entry
DbEntityEntry< Gets a
Same as Entry method but this generic method
<TEntity>( TEntity>
DbEntityEntry< does type check of passed EntityObject before
TEntity)
TEntity> object returning DBEntityEntry object
for the given
entity providing
access to
information
about the
entity and the
ability to
perform actions
on the entity.
Set(Type)

DBSet

Returns a
DbSet for the
specified type,
this allows
CRUD
operations to
be performed
for the given
entity in the
context.

CRUD operation.
ctx.Set(stud.GetType().BaseType).Add(studentEn
tity);
ctx.Set(stud.GetType().BaseType).Attach(student
Entity);
ctx.Set(stud.GetType().BaseType).Remove(stude
ntEntity);
var result =
ctx.Set(studentEntity.GetType().BaseType).SqlQu
ery("select * from student");
studentEntity.GetType() will return POCO Proxy
type.
studentEntity.GetType().BaseType should be use
to get an actual entity type.

P a g e | 32
Set<TEntity DBSet
>()

Returns a
DbSet for the
specified type,
this allows
CRUD
operations to
be performed
for the given
entity in the
context.

SaveChang int
es()

CRUD operation.
dbcontext.Set<Student>().Add(studentEntity);
dbcontext.Set<Student>().Attach(studentEntity)
;
dbcontext.Set<Student>().Remove(studentEntit
y);
var result = dbcontext.Set().SqlQuery("select *
from student");

Saves all
Save changes to the database:
changes made
in this context Dbcontext.SaveChanges();
to the
underlying
database.

Protected Methods:
Method Name

Return Type

ShouldValidateE bool
ntity

ValidateEntity

Description
Extension point allowing the user to override the
default behavior of validating only added and
modified entities.

DbEntityValidationR Extension point allowing the user to customize


esult
validation of an entity or filter out validation results.
Called by GetValidationErrors().

Public Properties:
Property
Name

Return Type

ChangeTrac DBChangeTracker
ker

Description
Provides access to features of the context that deal with
change tracking of entities.

Configuratio DBContextConfigur Provides access to configuration options for the context.


n
ation
Database

Database

Creates a database instance for this context and allows


you to perform creation, deletion or existence checks for
the underlying database.

Visit MSDN for more information of DBContext class.

P a g e | 33

Persistence in Entity Framework


Learn how to persist an entity so that it either inserts new row or updates an existing row or delete an
existing row in the database.

We need to consider two scenarios, connected scenario and disconnected scenario.

Connected Scenario: Connected scenario is when an entity is retrieved from the database and persist
using same context. Context object doesnt destroy between when entity retrival and persistence.

Disconnected Scenario: Disconnected scenario is when an entity is retrieved from the


database and modified using different contexts. Disconnected scenario is complex because
new context doesnt know anything about modified entity so you have to tell context that
what has changed in entity. In the below figure, client retrieve entity graph using Context 1
and then it perform some CUD (create, update, Delete) operations and then it saves entity
graph using Context 2. Context 2 doesnt know which operation has been performed on the
entity graph in this scenario.

P a g e | 34

CRUD Operation in Connected Scenario:

CRUD operation in connected scenario is fairly easy task because context automatically detact changes
happened in the entity provided AutoDetectChangesEnabled is true by default.

Following example show how you can add, update and delete entity using context and call
context.SaveChanges() method to update the database.
using (var context = new SchoolDBEntities())
{
var studentList = context.Students.ToList<Student>();
//Perform create operation
context.Students.Add(new Student() { StudentName = "New Student" });
//Perform Update operation
Student studentToUpdate = studentList.Where(s => s.StudentName ==
"student1").FirstOrDefault<Student>();
studentToUpdate.StudentName = "Edited student1";
//Perform delete operation
context.Students.Remove(studentList.ElementAt<Student>(0));
//Execute Inser, Update & Delete queries in the database
context.SaveChanges();
}

P a g e | 35
Note: If AutoDetectChangesEnabled is set to false then context cannot detect changes made to existing
entities so do not execute update query. You need to call context.ChangeTracker.DetectChanges() before
SaveChanges() in order to detect edited entities and mark their status Modified.

Context detects adding and deleting entity when performed only on DbSet. If you perform add and delete
entity on separate collection or list then it wont detect these changes.

Following code will NOT insert or delete student. It will only do update student:
using (var context = new SchoolDBEntities())
{
var studentList = context.Students.ToList<Student>();
//Add student in list
studentList.Add(new Student() { StudentName = "New Student" });
//Perform update operation
Student studentToUpdate = studentList.Where(s => s.StudentName ==
"Student1").FirstOrDefault<Student>();
studentToUpdate.StudentName = "Edited student1";
//Delete student from list
if (studentList.Count > 0)
studentList.Remove(studentList.ElementAt<Student>(0));
//SaveChanges will only do update operation not add and delete
context.SaveChanges();
}

Learn how to do CRUD operation in disconnected scenario in the next chapters.

Update Entity using DBContext


As we have learned about DBContext.Entry method in previous chapter, Entry method is useful to get
DBEntityEntry for given Entity.

Following statement attach entity into context and mark its state to Modified:

dbCtx.Entry(Entity).State = System.Data.EntityState.Modified;

Let's see how to update an existing single 'Standard' entity:

P a g e | 36
Student stud ;
// Get student from DB
using (var ctx = new SchoolDBEntities())
{
stud = ctx.Students.Where(s => s.StudentName == "New
Student1").FirstOrDefault<Student>();
}
// change student name in disconnected mode (out of DBContext scope)
if (stud != null)
{
stud.StudentName = "Updated Student1";
}
//save modified entity using new DBContext
using (var dbCtx = new SchoolDBEntities())
{
//Mark entity as modified
dbCtx.Entry(stud).State = System.Data.EntityState.Modified;
dbCtx.SaveChanges();
}

As you see in the above code snippet, we are doing following steps:
1. Get the existing student
2. Change student name out of DBContext scope (disconnected mode)
3. We pass modified entity into Entry method to get its DBEntityEntry object and then marking its
state as Modified
4. Calling SaveChanges to update student information into the database.
SaveChanges will send following update query to the database:
exec sp_executesql N'update [dbo].[Student]
set [StudentName] = @0, [StandardId] = @1
where ([StudentID] = @2)',N'@0 varchar(50),
@1 int,@2 int',@0='Updated Student1',@1=299,@2=267

So this way we can easily update an entity using DBContext.

In the next chapter we will learn how to update an one-to-one relationship entities.

Add Entity using DBContext


In this chapter we will learn how to add and save single entity using DbContext in disconnected scenario
which in-tern insert single row in database table.

P a g e | 37

We will see how to add single 'Standard' entity:


// create new Standard entity object
var newStandard = new Standard();
// Assign standard name
newStandard.StandardName = "Standard 1";
//create DBContext object
using (var dbCtx = new SchoolDBEntities())
{
//Add standard object into Standard DBset
dbCtx.Standards.Add(newStandard);
// call SaveChanges method to save standard into database
dbCtx.SaveChanges();
}

As you can see in above code snippet, first we have created new Standard entity object and set
StandardName to 'Standard 1'. Second, created new DBContext object and added newly created Standard
entity into Standards EntitySet. Third, calling SaveChanges method of DBContext which sends insert
query to the database.

This will result in following SQL query to the database:


exec sp_executesql N'insert [dbo].[Standard]([StandardName], [Description])
values (@0, null)
select [StandardId]
from [dbo].[Standard]
where @@ROWCOUNT > 0 and [StandardId] = scope_identity()',N'@0
varchar(50)',@0='Standard 1'

Alternatively, we can also add Standard entity into DBContext.Entry and mark it as Added which result in
same insert query:
dbCtx.Entry(newStandard).State = System.Data.EntityState.Added;

So this way you can add single entity.

In the next chapter we will learn how to add entities which has one-to-one relationship.

Delete Entity using DBContext


We used Entry() method of DbContext to mark EntityState to Modified in the previous chapter. Same way
we can use Entry() method to attach disconnected entity to the context and mark its state to Deleted.

P a g e | 38
using (var context = new SchoolDBEntities())
{
context.Entry(disconnectedTeacher).State = System.Data.EntityState.Deleted;
context.SaveChanges();
}

Above code results in following delete query which deletes the row from Teacher table.
delete [dbo].[Teacher]
where ([TeacherId] = @0)',N'@0 int',@0=1

Concurrency in Entity Framework:


Entity Framework supports Optimistic Concurrency by default. In the optimistic concurrency, EF saves
the entity to the database in the hope that the same data has not changed since the entity was loaded. If it
finds that data has changed then an exception is thrown and you must resolve the conflict before
attempting to save it again.

Let's see how you can handle optimistic concurrency with Student entity.

First of all, you need to have rowversion column in the Student table In order to handle concurrency with
Stuent entity. Rowversion is is a datatype in SQL Server that automatically generates unique binary
number whenever insert or update operation performed in a table. The rowversion datatype is just an
incrementing number. Rowevesion is synonym for the timestamp datatype. Both are same.

Create new column RowVersion in Student table with timestamp datatype as below:

P a g e | 39
Note: Value of RowVersion will be added and updated automatically by the databse in Insert and
Updateoperation.

Now, create new Entity Data Model or update an existing data model by right clicking on designer ->
Update Model From Database -> Refresh Student table. So now, you will see RowVersion property
added in the Student entity.

Now, you need to apply concurrency mode to fixed by right clicking on RowVersion property in the
Student entity (right click on RowVersion property not Student entity) -> select Property. Change
Concurrency Mode to Fixed from None in the property window as below:

EF will now include RowVersion column in the where clause whenever you do update operation and if
rowversion value is different than in where clause then it will throw DbUpdateConcurrencyExection.

Following code shows that User1 and User2 get the same student and update StudentName at the same
time:
Student student1WithUser1 = null;
Student student1WithUser2 = null;
//User 1 gets student
using (var context = new SchoolDBEntities())
{
context.Configuration.ProxyCreationEnabled = false;

P a g e | 40
student1WithUser1 = context.Students.Where(s => s.StudentID ==
1).Single();
}
//User 2 also get the same student
using (var context = new SchoolDBEntities())
{
context.Configuration.ProxyCreationEnabled = false;
student1WithUser2 = context.Students.Where(s => s.StudentID ==
1).Single();
}
//User 1 updates Student name
student1WithUser1.StudentName = "Edited from user1";
//User 2 updates Student name
student1WithUser2.StudentName = "Edited from user2";

now, User1 saves his changes before User2. So when user2 trys to save the changes, he will get
concurrency exection:
//User 1 saves changes first
using (var context = new SchoolDBEntities())
{
try
{
context.Entry(student1WithUser1).State = EntityState.Modified;
context.SaveChanges();
}
catch (DbUpdateConcurrencyException ex)
{
Console.WriteLine("Optimistic Concurrency exception occured");
}
}
//User 2 saves changes after User 1.
//User 2 will get concurrency exection
//because CreateOrModifiedDate is different in the database
using (var context = new SchoolDBEntities())
{
try
{
context.Entry(student1WithUser2).State = EntityState.Modified;
context.SaveChanges();
}
catch (DbUpdateConcurrencyException ex)
{
Console.WriteLine("Optimistic Concurrency exception occured");
}
}

Concurrency in Code-First:

You can create timestamp property in code-first by usng [Timestamp] attribute. Make sure property type
is byte[] because timestamp is binary in C#.
[Timestamp]
public byte[] RowVersion { get; set; }

P a g e | 41
EF includes property in where clause in update operation if the property is marked withTimestamp
attribute.

You can resolve concurrency exection many ways. Visit msdn on detailed information on how to resolve
optimistic concurrency.

Download sample project for concurrency demo.

Download sample project for the demo.

Entity Framework 6.0 Introduction:


Welcome to Entity Framework 6 tutorials section. Here, you will learn about new features introduced in
Entity Framework 6.0 with Visual Studio 2012.

Entity Framework 6.0 has introduced many new exciting features for database first (designer) and codefirst approaches.

Features for Database First (Designer) and Code-First Both:


1. Connection resiliency
2. Asynchronous query and save
3. Code-based configuration
4. Database command logging
5. Database command interception
6. Dependency Resolution
7. DbSet.AddRange/RemoveRange
8. Better Transaction Support
9. Pluggable pluralisation and singularization service
10. Testability improvements

P a g e | 42
11. Creating context with an open connection
12. Improved performance and warm-up time

Features for Code-First:


1. Custom conventions
2. Insert, update & delete stored procedures for entity CUD operation
3. Index attribute (EF 6.1)
4. Multiple context per database
5. Nested entity types
6. Custom migration operations
7. Configurable migration history table

Visit msdn for detail information on EF 6.x.

Click Next to learn some features of Entity Framework 6.x.


You can take advantage of asynchronous execution of .net 4.5 with entity framework. EF 6 has a ability to
execute a query and command asynchronously using DbContext.

Lets see how to execute asynchronous query first and then we will see asynchronous call to
context.SaveChanges.

Asynchronous Query:
private static async Task<Student> GetStudent()
{
Student student = null;
using (var context = new SchoolDBEntities())
{
Console.WriteLine("Start GetStudent...");
student = await (context.Students.Where(s => s.StudentID ==
1).FirstOrDefaultAsync<Student>());

P a g e | 43
Console.WriteLine("Finished GetStudent...");
}
return student;
}

As you can see in the above code, GetStudent method marked with async to make it asynchronous.
Return type of asynchrounous method must be Task. GetStudent returns object of Student entity so return
type must be Task<Student>.

Also, query is marked with await, this freed calling thread to do something else till it executes query and
returns data. We have used FirstOrDefaultAsync extension method of System.Data.Entity. you may use
other extension methods appropriately like SingleOrDefaultAsync, ToListAsyn etc.

Asynchronous Save:

You can call context.SaveChanges asynchronously the same way as async query:

Transaction support:
Entity Framework by default wraps Insert, Update or Delete operation in a transaction whenever you
execute SaveChanges(). EF starts new transaction for each operations and complete the transaction when
it operation finishes. When you execute another such operation a new transaction is started.

EF 6 has introduced database.BeginTransaction and Database.UseTransaction to provide more control


over transaction. Now, you can execute multiple operations in a single transaction as below:
using (System.Data.Entity.DbContextTransaction dbTran =
context.Database.BeginTransaction( ))
{
try
{
Student std1 = new Student() { StudentName = "newstudent" };
context.Students.Add(std1);
context.Database.ExecuteSqlCommand(
@"UPDATE Student SET StudentName = 'Edited Student Name'" +
" WHERE StudentID =1"
);
context.Students.Remove(std1);
//saves all above operations within one transaction
context.SaveChanges();
//commit transaction

P a g e | 44
dbTran.Commit();
}
catch (Exception ex)
{
//Rollback transaction if exception occurs
dbTran.Rollback();
}
}

database.UseTransaction allows the DbContext to use a transaction which was started outside of the
Entity Framework.

DbSet.AddRange & DbSet.RemoveRange:


DbSet in EF 6 has introduced new methods AddRange & RemoveRange. DbSet.AddRange adds
collection(IEnumerable) of entities to the DbContext, so you don't have to add each entity individually.
IList<Student> newStudents = new List<Student>();
newStudents.Add(new Student() { StudentName = "Student1 by addrange" });
newStudents.Add(new Student() { StudentName = "Student2 by addrange" });
newStudents.Add(new Student() { StudentName = "Student3 by addrange" });
using (var context = new SchoolDBEntities())
{
context.Students.AddRange(newStudents);
context.SaveChanges();
}

Same way, use DbSet.RemoveRange to remove collection of entities from DbSet.


IList<Student> existingStudents = ..
using (var context = new SchoolDBEntities())
{
context.Students.RemoveRange(existingStudents);
context.SaveChanges();
}

Custom Code-First Conventions:


Code First has a set of default behaviours for the models that refer to as conventions. EF 6 provides
ability to define your own custom conventions which will be default behaviour for your models.

There are two main types of Conventions, Configuration Conventions and Model Conventions.

Configuration Conventions:

P a g e | 45
Configuration Conventions are a way to configure entities without overriding default behaviour provided
in the Fluent API. You can define a configuration convention inside your OnModelCreating event or in a
custom Convention Class in a similar way to how you would define normal entity mappings with the
Fluent API.

For example, you can define primary key of entity that has property named {entity name} _ID. E.g.
Student_ID property of Student entity will be primary key:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder
.Properties()
.Where(p => p.Name == p.DeclaringType.Name + "_ID")
.Configure(p => p.IsKey());
base.OnModelCreating(modelBuilder);
}

Following example show how to set string length of Description property in all entities:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder
.Properties()
.Where(p => p.Name == "Description")
.Configure(p => p.HasMaxLength(200));
base.OnModelCreating(modelBuilder);
}

You can also define custom class for this convention by deriving Convention class as below:
public class PKConvention : Convention
{
public PKConvention()
{
.Properties()
.Where(p => p.Name == p.DeclaringType.Name + "_ID")
.Configure(p => p.IsKey());
}
}

Configure custom convention as below:


protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Add<PKConvention>();
}

Model Conventions:

P a g e | 46
Model Conventions is based on the underlying model metadata. There are conventions for CSDL and
SSDL both. Create class that implements IConceptualModelConvention form CSDL conventions and
implement IStoreModelConvention for SSDL convention.

Visit codeplex documentation for more information.

Download code-first sample project for custom conventions demo.

Code First - Insert, Update, Delete Stored


Procedure Mapping:
Entity Framework 6 Code First provides ability to create and use stored procedure for add, update and
delete operation. It was not possible in the previous versions of Entity Framework.

Student Entity:
class Student
{
public Student()
{
}
public int Student_ID { get; set; }
public string StudentName { get; set; }
}

Following example automatically create stored procedure for Student entity using Fluent API.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Student>()
.MapToStoredProcedures();
}

Above code will create three procedures Student_Insert, Student_Update and Student_Delete.
Student_Insert and Student_Update stored procedures has parameters name corresponds to the property
names. Student_Delete will have primary key property StudentID parameter.

P a g e | 47
You can also change stored procedure and parameters name as below:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Student>()
.MapToStoredProcedures(p => p.Insert(sp =>
sp.HasName("sp_InsertStudent").Parameter(pm => pm.StudentName, "name").Result(rs =>
rs.Student_ID, "Student_ID"))
.Update(sp => sp.HasName("sp_UpdateStudent").Parameter(pm =>
pm.StudentName, "name"))
.Delete(sp => sp.HasName("sp_DeleteStudent").Parameter(pm =>
pm.Student_ID, "Id"))
);
}

If you want all your entities to use stored procedures then do as following:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Types().Configure(t => t.MapToStoredProcedures());
}

Limitations:

Only Fluent API can be used to map stored procedures. You cannot use Data Annotation attributes
in EF 6 for stored procedure mapping.

You cannot use mixture of stored procedure and query to add, update and delete operation on the
same entity. You can either use stored procedure or SQL query for all add, update and delete
operation with entity.

Download sample project for demo.

Visit codeplex documentation for more information.

Previous
Next

Index Attribute:

P a g e | 48
Entity Framework 6 provides Index attribute to create Index on particular column in the database as
below:
class Student
{
public Student()
{
}
public int Student_ID { get; set; }
public string StudentName { get; set; }
[Index]
public int RegistrationNumber { get; set; }
}

By default, Index name will be IX_{property name}. However, you can also change Index name.

You can also make it Clustered index by specifying IsClustered = true and unique index by specifying
IsUnique=true.
[Index( "INDEX_REGNUM", IsClustered=true, IsUnique=true )]
public int RegistrationNumber { get; set; }

You might also like