Introduction to the Entity Framework
Entity Framework is an object-relational mapping technology that enables .NET developers to work with relational data by using domain-specific objects. It eliminates the need for most of the data-access code that developers usually need to write. Entity Framework is the recommended object-relational mapping (ORM) modeling technology for new .NET applications.
The ADO.NET Entity Framework is an object-relational mapping (ORM) framework that offers an abstraction of ADO.NET to get an object model based on the referential databases. You can use different programming models with the Entity Framework: Model First, Database First, and Code First. Both Model First and Database First provide mapping information with a mapping file. Using Code First, mapping information is all done via C# code. This tutorial provides information about all these programming models.
You will learn about the mappings between the database and the entity classes using the Conceptual Schema Definition Language (CSDL), the Store Schema Definition Language (SSDL), and the Mapping Schema Language (MSL). Different relationships between entities are covered, such as one table per hierarchy of objects, one table per type, and n-to-n relationships.
This tutorial also describes different ways to access the database from the code directly with the EntityClient provider, using Entity SQL or helper methods that create Entity SQL, and using LINQ to Entities. Also described are object tracking and how the data context holds change information for updating data. Finally, you'll learn how POCO (Plain Old CLR Objects) can be used with the Entity Framework, and how to use the Code First programming model.
The ADO.NET Entity Framework provides a mapping from the relational database schema to objects. Relational databases and object-oriented languages define associations differently. For example, the sample database Formula1 contains the Racers
and RaceResults
tables. To access all the RaceResults
rows for a racer, you need to do a SQL join
statement. With object-oriented languages, it is more common to define a Racer
class and a RaceResult
class and access the race results of a racer by using a RaceResults
property from the Racer
class.
For object-relational mapping before using the Entity Framework, it has been possible to use the DataSet
class and typed data sets. Data sets are very similar to the structure of a database containing DataTable
, DataRow
, DataColumn
, and DataRelation
classes instead of offering object-support. The ADO.NET Entity Framework supports directly defining entity classes that are completely independent of a database structure and mapping them to tables and associations of the database. Using objects with the application, the application is shielded from changes in the database.
The ADO.NET Entity Framework offers Entity SQL to define entity-based queries to the store (an extension to T-SQL). LINQ to Entities makes it possible to use the LINQ syntax to query data. An object context acts as a bridge regarding entities that are changed, retaining information for when the entities should be written back to the store. Microsoft moves more and more parts of the core framework into NuGet packages, which means that it is not necessary to wait for an update of the complete .NET Framework to deliver new features. With the latest versions of the Entity Framework, more and more parts moved out into a NuGet package. As of Entity Framework 6 (which is discussed in this book), the framework is now completely in a NuGet package. To not get in conflict with previous versions, some parts now have new namespaces, but the classes and members remain the same. The namespaces that contain classes from the ADO.NET Entity Framework are listed in the following table:
Namespaces that include the ADO.NET Entity Framework classes.
Namespace |
Description |
System.Data |
A main namespace for ADO.NET. With the ADO.NET Entity Framework, this namespace contains exception classes related to entities — for example, MappingException and QueryException.
|
System.Data.Core.Common |
Contains classes to build an expression tree.
|
System.Data.Core.Common .CommandTrees |
The body of the Web document displayed in the browser window |
System.Data.Entity |
Contains classes for the Code First development model. |
System.Data.Entity.Design |
The list of previously visited Web sites within the browser window |
System.Data.Entity.Core. EntityClient |
Specifies classes for the .NET Framework Data Provider to access the Entity Framework. EntityConnection, EntityCommand, and EntityDataReader can be used to access the Entity Framework. |
Entity Framework Mapping
With Model First and Database First, the ADO.NET Entity Framework offers several layers to map database tables to objects. With Database First you can start with a database schema and use a Visual Studio item template (ADO.NET Entity Data Model) to create the complete mapping. You can also start designing entity classes with the designer (Model First) and map it to the database such that the tables and the associations between the tables can have a very different structure. The layers that need to be defined are as follows:
- Logical: Defines the relational data.
- Conceptual: Defines the .NET entity classes.
- Mapping: Defines the mapping from .NET classes to relational tables and associations.
Note: To view the code samples referenced in the text below, download the file Entity Framework Samples. Unzip the file and open the solution in Visual Studio.
Logical Layer
The logical layer is defined by the Store Schema Definition Language (SSDL) and describes the structure of the database tables and their relationships. The following code uses SSDL to describe the three tables: Books, Authors, and BooksAuthors. The EntityContainer
element describes all the tables with EntitySet
elements, and associations with AssociationSet
elements. The parts of a table are defined with the EntityType
element. With EntityType Books
you can see the columns Id
, Title
, Publisher
, and ISBN
defined by the Property
element. The Property
element contains XML attributes to define the data type. The Key
element defines the primary key of the table. You can find the following code in the code file BooksDemo/BooksModel.edmx.
Conceptual Layer
The conceptual layer defines .NET entity classes. This layer is created with the Conceptual Schema Definition Language (CSDL).
Figure 33-2 shows the entities Author and Book defined with the ADO.NET Entity Data Model Designer.
The following code (found in code file BooksDemo/BooksModel.edmx) is the CSDL content that defines the entity types Book and Author. Review the code that was created from the Books database in the Book.cs and Auhtor.cs files.
The entity is defined by an EntityType
element, which contains Key
, Property
, and NavigationProperty
elements to describe the properties of the created class. The Property
element contains attributes to describe the name and type of the .NET properties of the classes generated by the designer. The Association
element connects the types Author
and Book
. Multiplicity="*"
means that one Author
can write multiple Books
, and one Book
can be written by multiple Authors
.
Mapping Layer
The mapping layer maps the entity type definition from the CSDL to the SSDL using the Mapping Specification Language (MSL). The following specification (code file BooksDemo/BooksModel.edmx
) includes a Mapping
element that contains the EntityTypeMapping
element to reference the Book
type of the CSDL and it defines the MappingFragment
to reference the Authors
table from the SSDL. The ScalarProperty
maps the property of the .NET class with the Name
attribute to the column of the database table with the ColumnName
attribute.
Standard Query Operators Defined By The Enumerable
Class
Standard Query Operators |
Description |
Where
OfType<TResult>
|
Filtering operators define a restriction to the elements returned. With the Where query operator you can use a predicate; for example, a Lambda expression that returns a bool . OfType<TResult> filters the elements based on the type and returns only the elements of the type TResult . |
Select
SelectMany |
Projection operators are used to transform an object into a new object of a different type. Select and SelectMany define a projection to select values of the result based on a selector function. |
OrderBy
ThenBy
OrderByDescending
ThenByDescending |
Sorting operators change the order of elements returned. OrderBy sorts values in ascending order; OrderByDescending sorts values in descending order. ThenBy and ThenByDescending operators are used for a secondary sort if the first sort gives similar results. Reverse reverses the elements in the collection. |
Join
GroupJoin |
Join operators are used to combine collections that might not be directly related to each other. With the Join operator a join of two collections based on key selector functions can be done. This is similar to the JOIN you know from SQL. The GroupJoin operator joins two collections and groups the results. |
GroupBy
ToLookup
|
Grouping operators put the data into groups. The GroupBy operator groups elements with a common key. ToLookup groups the elements by creating a one-to-many dictionary |
Any
All
Contains
|
Quantifier operators return a Boolean value if elements of the sequence satisfy a specific condition. Any, All, and Contains are quantifier operators. Any determines if any element in the collection satisfies a predicate function; All determines if all elements in the collection satisfy a predicate. Contains checks whether a specific element is in the collection.
|
Take
Skip
TakeWhile
SkipWhile
|
Partitioning operators return a subset of the collection. Take, Skip, TakeWhile, and SkipWhile are partitioning operators. With these, you get a partial result. With Take, you have to specify the number of elements to take from the collection; Skip ignores the specified number of elements and takes the rest. TakeWhile takes the elements as long as a condition is true.
|
Distinct
Union
Intersect
Except
Zip |
Set operators return a collection set. Distinct removes duplicates from a collection. With the exception of Distinct, the other set operators require two collections. Union returns unique elements that appear in either of the two collections. Intersect returns elements that appear in both collections. Except returns elements that appear in just one collection. Zip combines two collections into one. |
First
FirstOrDefault
Last
LastOrDefault
ElementAt
ElementAtOrDefault
Single
SingleOrDefault
|
Element operators return just one element. First returns the first element that satisfies a condition. FirstOrDefault is similar to First, but it returns a default value of the type if the element is not found. Last returns the last element that satisfies a condition. With ElementAt, you specify the position of the element to return. Single returns only the one element that satisfies a condition. If more than one element satisfies the condition, an exception is thrown.
|
Count
Sum
Min
Max
Average
Aggregate
|
Aggregate operators compute a single value from a collection. With aggregate operators, you can get the sum of all values, the number of all elements, the element with the lowest or highest value, an average number, and so on.
|
ToArray
AsEnumerable
ToList
ToDictionary
Cast<TResult>
|
Conversion operators convert the collection to an array: IEnumerable, IList, IDictionary, and so on.
|
Empty
Range
Repeat
|
Generation operators return a new sequence. The collection is empty using the Empty operator; Range returns a sequence of numbers, and Repeat returns a collection with one repeated value. |
LINQ to Entities Query Syntax
LINQ to Entities queries can be composed in two different syntaxes: query expression syntax and method-based query syntax. Query expression syntax is new in C# 3.0 and Visual Basic 9.0, and it consists of a set of clauses written in a declarative syntax similar to Transact-SQL or XQuery. However, the .NET Framework common language runtime (CLR) cannot read the query expression syntax itself. Therefore, at compile time, query expressions are translated to something that the CLR does understand: method calls. These methods are known as the standard query operators. As a developer, you have the option of calling them directly by using method syntax, instead of using query syntax. For more information, see Query Syntax and Method Syntax in LINQ.
Note: In order to use LINQ queries in your code you will need to include a using directive for the System.Linq namespace.
Query Expression Syntax
Query expressions are a declarative query syntax. This syntax enables a developer to write queries in a high-level language that is formatted similar to Transact-SQL. By using query expression syntax, you can perform even complex filtering, ordering, and grouping operations on data sources with minimal code. This code sample shows an example of query expression syntax:
IQueryable<Customer> customers =
from c in context.Customers
where c.ContactName.Length > 5
orderby c.ContactName
select c;
foreach (Customer c in customers)
{
Label1.Text += c.ContactName + ": " + c.ContactTitle + "<br />";
}
Method-based Query Syntax
Another way to compose LINQ to Entities queries is by using method-based queries. The method-based query syntax is a sequence of direct method calls to LINQ operator methods, passing lambda expressions as the parameters. For more information, see Lambda Expressions. This code sample shows an example of method-based query syntax.
IQueryable<Customer> customers =
context.Customers.Where(c => c.ContactName.Length > 5).OrderBy(c => c.ContactName);
foreach (Customer c in customers)
{
Label1.Text += c.ContactName + ": " + c.ContactTitle + "<br />";
}
Entity Framework Demo
- Create a New Empty ASP.NET Web Application (.NET Framework) Project
- Add a new folder to the project named Models
- Right-Click on the Models folder and add an ADO.NET Entity Data Model
- Add a new Web form to the project and add a Label control to it.
- Press F7 to open the code-behind file for the Web form and replace all the template code with the following:
Note: In the examples below, replace <namespace> with the actual namespace being used in your project.
using System;
using <namespace>.Models;
namespace <namespace>
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Label1.Text = "";
using (var context = new Northwind())
{
foreach (var customer in context.Customers)
{
Label1.Text += customer.ContactName + "<br />";
}
}
}
}
}
This example uses model-based query syntax to order customers by the ContactName field:
using System;
using <namespace>.Models;
namespace <namespace>
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Label1.Text = "";
using (var context = new Northwind())
{
var customers = context.Customers.OrderBy(c => c.ContactName);
foreach (var c in customers)
{
Label1.Text += c.ContactName + ": " + c.ContactTitle + "<br />";
}
}
}
}
}
Note: the OrderBy method sorts in ascending order, to sort in descending order use the OrderByDescending method.
Video: Using Visual Studio to Perform a Database First Migration
Entity Framework Links of Interest
Entity Data Model Tools in Visual Studio - EF data model tools assist developers in designing, creating, and modifying database entities in Visual Studio.
Introduction to the Entity Framework - This Web-based tutorial will introduce the reader to the ADO.NET Entity Framework and how to use it in Visual Studio 2015.
Entity Framework Code Examples Used In Class Demos - Code used in the Entity Framework in-class demo.
Introduction to the Entity Framework - MSDN Entity Framework Introduction
ASP.NET Core and Entity Framework Core - This link will take you to a tutorial that teaches how to create ASP.NET Core MVC web applications that use Entity Framework Core for data access. The tutorials require Visual Studio 2017.
Entity Framework @ MSDN .NET Developer - Entity Framework documentation on the MSDN .NET Development site.
The ADO.NET Entity Framework Home Page - The ADO.NET Entity Framework is Microsoft's recommended data access technology for new applications.The ADO.NET Entity framework gives developers the power to read, write, and update their databases using C# models and LINQ.
Compare EF Core & EF6.x - There are two versions of Entity Framework, Entity Framework Core and Entity Framework 6.x; this articles provides a brief comparison of each.
Entity Framework @ MSDN Data Developer Center - Entity Framework fork on the MSDN Data Developer Center site.
Entity Framework Class Library 6.0 - Entity Framework 6.0 Reference documentation.
Entity Framework Model First Video - This video and step-by-step walkthrough provide an introduction to Model First development using Entity Framework.
What's new in Entity Framework Core - Find out about new features available in Entity Framework Core.
Entity Framework Code First Migrations - In ASP.NET MVC if you makes changes to your database you will need to perform a code first migration in order to update your MVC application. This MSDN article provides an overview of code first migrations in ASP.NET Entity framework.
⇑ Table of Contents