Entity Framework architectural components
Entity Framework comprises the following components:
- The Entity Data Model
- LINQ to Entities
- Entity Client
- Entity SQL
- The Object Services Layer
Note that the Conceptual Model Layer, Mapping Layer, and Logical Model Layer are all parts of the EDM. The following image illustrates the layers of the ADO.NET Entity Framework and how they are related to each other:
We will now discuss each of the components of the Entity Framework technology stack in the following sections.
The Entity Data Model
The
Entity Data Model (EDM), an extended entity relationship model, is the core of Entity Framework. You can generate an EDM using the EDMGen.exe
command-line tool or using the ADO.NET EDM Designer—a new Visual Studio template. We will discuss how an EDM can be generated from a relational schema in the next chapter.
For additional information, please refer to http://msdn.microsoft.com/en-us/library/bb896270(v=vs.110).aspx.
The following image illustrates where exactly the EDM fits in:
The EDM abstracts the logical or the relational schema and exposes the conceptual schema of the data using a three-layered approach. It comprises the following layers:
- The Conceptual Model Layer or the Conceptual Data Definition Language Layer (C-Space)
- The Mapping Layer or the Mapping Schema Definition Language layer (C-S Space)
- The Storage Layer or the Logical Layer or the Store Space Definition Language Layer (S-Space)
The following image illustrates the layers of the EDM:
Let's explain each of these layers in detail:
- The Conceptual Layer or the C-Space Layer is responsible for defining the entities and their relationships. It defines your business objects and their relationships in XML files. The C-Space is modeled using CSDL and comprises EntityContainer, EntitySets, AssociationSets, AssociationTypes, EntityTypes, and functions. You can query this layer using Entity SQL or ESQL (EntityConnection, EntityCommand, and EntityDataReader).
- The C-S Mapping Layer is responsible for mapping the conceptual and the logical layers. That is, it maps the business objects and the relationships defined in the conceptual layer with the tables and relationships defined in the Logical layer. It is a mapping system created in XML, which links or maps the conceptual and the Logical layers. The C-S Mapping Layer is modeled using Mapping Storage Layer or the MSL.
- The Logical or the Storage Layer (also called the S-Space) represents the schema of the underlying database. This comprises tables, stored procedures, views, and functions. It is modeled using SSDL and queried using the database providers. A database provider is an API to connect to and perform CRUD operations against a database. As an example, if the database in use is SQL Server, the ADO.NET data provider for SQL Server will be used. Hence, we use SQLConnection, SQLCommand, SQLDataReader, and SQLDataAdapter using T-SQL or PL-SQL if our data store is a SQL database.
Here is what a typical EDM looks like:
How is the EDM represented?
The EDM uses the following three types of XML files to represent the C-Space, C-S Space, and the S-Space respectively:
- Conceptual Schema Definition Language (.CSDL): This represents the C-S Space and is used to map the entity types used in the conceptual model
- Mapping Schema Language (.MSL): This represents the C-S Space and is used to map the logical model to the conceptual model
- Store Schema Definition Language (.SSDL): This represents the S-Space and is used to map the schema information of the Logical layer
Note
If you use the ADO.NET EDM Designer tool to generate your EDM, you will have one
.edmx
file that contains the CSDL, MSL, and SSDL sections bundled into one single file. At runtime, the.csdl
,.msl
, and.ssdl
files are created in the application's output directory.
These files store the metadata information as XML for each of the preceding layers.
Note
You can also create abstract and complex types in your EDM. You can derive from an abstract type to create sub-types, but no instance of the abstract type can be created. You can also create complex types. That is, types that don't have any identity of their own. A typical example of a complex type is the Address
type.
We will skip further discussion on each of the sections of an EDM until Chapter 3, Entities, Relationships, and the Entity Data Model.
The Object Model (O-Space)
When working with Entity Framework, you will have an Object Model on top of all the EDM layers. You need to model the Object Model using .NET objects. The following figure illustrates how the Object Model fits in with the EDM layers:
The Object Model layer contains .NET objects and a collection of .NET objects, types, properties, and methods. You can use the Object Model or the O-Space Model to query your business objects, or the collections of your business objects, using LINQ to Entities or Entity SQL. The C-Space and O-Space models are actually mapped by the O-C Mapping Layer using code attributes applied to the O-Space Model.
LINQ to Entities
LINQ is a query translation pipeline that has been introduced as part of the C# 3.0 library. It comprises a set of query operators for different data sources (LDAP, objects, CSV, XML, entities, SQL, and so on). It is an extension of the C# language (it's actually a series of extension methods) and provides a simplified framework to access relational data in a strongly typed, object-oriented manner.
LINQ to Entities is a Microsoft technology that enables you to query your business objects from within the language in a strongly typed manner. You can use LINQ to Entities, a superset of LINQ to SQL, to query data against a conceptual data model, namely, the Entity Data Model. You will learn more about LINQ and LINQ to Entities in Chapter 6, Working with LINQ to Entities.
Here is an example of a typical LINQ to Entities query:
AdventureWorksEntities ctx = new AdventureWorksEntities(); var query = from e in ctx.Employees select e; foreach (var employee in query) Console.WriteLine (employee.EmployeeID);
Note
LINQ to Entities rests on top of Entity Framework's Object Services Layer and the LINQ to Entities queries are internally translated to canonical query trees. This, in turn, gets converted internally to corresponding SQL queries in a form expected by your underlying database.
Entity Client
The Entity Framework allows you to write programs against the EDM and also add a level of abstraction on top of the relational model. This isolation of the logical view of data from the Object Model is accomplished by expressing queries in terms of abstractions using an enhanced query language called Entity SQL.
EntityClient, the gateway to entity-level queries, is the Entity Framework's counterpart of ADO.NET's SQL client or Oracle client that uses Entity SQL or E-SQL to query the conceptual model. You create a connection using the entity connection, execute commands through entity commands, and retrieve the result sets as entity data readers. The MSDN states:
"The EntityClient provider is a data provider used by Entity Framework applications to access data described in a conceptual model."
Entity SQL
Entity SQL is a data store independent derivative of T-SQL that supports entity inheritance and relationships. You can use it to query data using the conceptual schema. You can even build your own dynamic queries. These E-SQL queries are internally translated to data store dependent SQL queries. This translation of the E-SQL queries to their data store-specific query language like T-SQL, (it doesn't need to be only T-SQL, however, it is the supported one), is handled by the Entity Framework. Entity SQL or E-SQL may not be as strongly typed as LINQ is, but you have the flexibility of executing dynamic queries using it, much like T-SQL.
Note
Strongly typed data access is one of the most striking features of LINQ. LINQ queries are checked at compile time. This is unlike SQL queries, which are only detected at runtime.
But, why do you need Entity SQL when you have LINQ to Entities to query data through your EDM? You can, using Entity SQL, compose queries that are difficult to determine until the time the query is executed. On a different note, Entity SQL is a full text-based query language that you can use in much the same way as you use the ADO.NET data providers.
Here is an example that shows how you can use Entity SQL to insert data into your applications:
using (EntityConnection conn = new EntityConnection("Name=PayrollEntities")) { try { conn.Open(); EntityCommand cmd = conn.CreateCommand(); cmd.CommandText = "PayrollEntities.AddNewEmployee"; cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters.AddWithValue("FirstName", "Joydip"); cmd.Parameters.AddWithValue("LastName", "Kanjilal"); cmd.Parameters.AddWithValue("Address", "Hyderabad"); cmd.Parameters.AddWithValue("DepartmentID", 4); cmd.ExecuteNonQuery(); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } }
Note
To query data from the EDM, you have three choices—Entity SQL, LINQ to Entities, and Object Services.
Avoiding complex joins
You can use Entity SQL to avoid complex joins as you will typically be querying against a conceptual model of the data. As an example, if we want to display employee names and the department names in which they work, we would have to join the information of the Employee
and the Department
tables and then filter the unwanted columns to retrieve only the information that is required. Such traversals become a nightmare as you add additional tables and therefore require more complex joins.
When you implement your Object Model using object-oriented programming languages, you expose the object's relationships to other objects of its kind using properties. This is in contrast to the approach we just discussed. Hence, designing an Object Model using this approach is cumbersome. This is exactly where Entity Framework fits in; it represents the conceptual and logical model of data while using grammar that is common to both.
Here is a code snippet that explains how you can use Entity SQL to avoid complex joins in your application's code. The following T-SQL query can be used to retrieve employee data split across three tables, namely, Employee
, Department
, and Salary
:
Select Employee.FirstName, Employee.LastName, Department.DepartmentName, Salary.Basic from Employee INNER JOIN Department on Department.DepartmentID = Employee.DepartmentID INNER JOIN Salary on Salary.EmployeeID = Employee.EmployeeID
This is how you would use Entity SQL to achieve the same result:
Select FirstName, LastName, DepartmentName, Basic from Employee
In the previous example, EmployeeData
is an entity that has been derived from the Employee
, Department
, and Salary
entities.
The Object Services Layer
As well as querying the conceptual model, you might, at some point, have to work with entities such as in-memory objects or a collection of in-memory objects. To do this, you need Object Services. You can use it to query data from almost any data store, and with less code.
Note
You can query data from the EDM by either using Object Services or EntityClient. However, if you require change tracking, be aware that only Object Services provides this feature. Note that in either case, the ADO.NET data providers are responsible for talking to the underlying database.
Note that the Object Services Layer internally uses an ObjectQuery
object for query processing. To use object services, you should include the System.Data.Objects
and System.Data.Objects.DataClasses
namespaces.
Here is an example that shows how you can use Object Services to retrieve data:
using (ObjectContext ctx = new ObjectContext("Name= PayrollEntities")) { ObjectQuery<Employee> data = ctx.CreateQuery<Employee>("PayrollEntities.Employees"); foreach (Employee emp in data) { Console.WriteLine(emp.EmployeeID); } }
In addition to enabling you to perform create, read, update, and delete (CRUD) operations, the Object Services Layer provides the following additional services:
- Change tracking
- Lazy loading
- Inheritance
- Optimistic concurrency
- Merging data
- Identity resolution
- Support for querying data using Entity SQL and LINQ to Entities
You will learn more about Object Services later in the book. The Object Services Layer leverages an Object Query object internally to process the data. Note that the Object Services Layer supports querying data using both Entity SQL and LINQ to Entities.
Features and benefits at a glance
Here is a quick look at some of the features and benefits of Entity Framework:
- It provides support for an increased level of abstraction on top of the underlying data store
- It provides support for extensibility and seamless querying of data using Entity SQL and LINQ
- It is a flexible schema that can be used to store the mapping information
- There is a reduction in the amount of Kilo Lines of Code (KLOC) needed to write data access code in your applications
- It contains a powerful Object Services Layer
- It provides support for a full text-based query language
- It provides support for persistence ignorance
- IT provides support for lazy loading
Note
KLOC refers to Kilo Lines of Code, a unit of measuring the amount of source code in your programs.