Entity Framework, a quickstart Florin−Tudor Cristea, Microsoft Student Partner
The ADO.NET Entity Framework (EF) supports data-centric applications and services, and provides a platform for programming against data that raises the level of abstraction from the logical relational level to the conceptual level. By enabling developers to work with data at a greater level of abstraction, the EF supports code that is independent of any particular data storage engine or relational schema.
The Entity Data Model (EDM) is a set of concepts that describe the structure of data, regardless of its stored form. In some ways, it is similar to a database view in that it can consolidate information from multiple sources. But it goes beyond a view in several ways. First, unlike a view, the conceptual EDM includes information about the source of the data so that the tools have enough information about the creation.
This metadata indicates where the values came from and consequently where they will go when updated. Additionally, the EDM includes the ability to store both objects and relationships necessary to create fully dynamic object hierarchies in a conceptual model. The EF separates the physical from the logical models by using a series of XML- based mapping files.
In the EF, the physical database is mapped to a logical model using a one-to-one relationship between the tables and logical layer entities. The logical entities are defined through an XML-based Store Schema Definition Language (SSDL) file. These mappings are similar to those definable in LINQ to SQL.
The EF moves beyond LINQ to SQL by using another XML-based file (Mapping Schema Language or MSL) to map the logical model to a conceptual model. The conceptual model is yet another XML file using a Conceptual Schema Definition Language (CSDL). These conceptual entities can be further converted into strongly typed objects if desired.
With the EDM established, we can query it with a string-based query language called Entity SQL. In addition, our LINQ knowledge can be applied against the EDM by using LINQ to Entities. The separation of layers we get from the EDM allows for an increased separation between the physical and logical. This allows us to change our data model and mapping structures and leave our application intact.
Physical Logical SSDL Mapping MSL Conceptual CSDL Author User Address Publisher Author Entity Publisher Entity AuthorClass PublisherClass Layers of the Entity Framework
The EF supports the EDM for defining data at the conceptual level. When using the ADO.NET Entity Data Model Designer, conceptual model, storage model, and mapping information is contained in an.edmx file. The EF also enables developers to program directly against the data types defined at the conceptual level as common language runtime (CLR) objects.
The EF provides tools to generate an.edmx file and the related CLR objects based on an existing database. This reduces much of the data access code that used to be required to create object-based data application and services, and makes it faster to create object-oriented data applications and services from an existing database.
The tools also allow you to build a conceptual model first, then automatically generate related CLR objects and a supporting database.
us/library/bb aspx Task 1: creating the School sample database Create the School database schema and load data into the database. SQL Server Express Utility Scripts/CreateSchool.sql
Task 2: creating the course manager application Create a Windows Forms application to access data in the School model. closeForm_Click: this.Close()
Task 3: generating the School entity data model Use Visual Studio tools to generate model and mapping information based on the School database.
Task 4: querying entities and associations Create queries against the entities and associations in the School model, and bind controls to the results of those queries. using System.Data.Objects; using System.Data.Objects.DataClasses; private SchoolEntities schoolContext;
courseViewer_Load: // Initialize the ObjectContext. schoolContext = new SchoolEntities(); // Define a query that returns all Department // objects and course objects, ordered by name. var departmentQuery = from d in schoolContext.Departments.Include("Courses") orderby d.Name select d; try { // Bind the ComboBox control to the query, // which is executed during data binding. // To prevent the query from being executed multiple times during binding, // it is recommended to bind controls to the result of the Execute method. this.departmentList.DisplayMember = "Name"; this.departmentList.DataSource = ((ObjectQuery)departmentQuery).Execute(MergeOption.AppendOnly); } catch (Exception ex) { MessageBox.Show(ex.Message); }
departmentList_SelectedIndexChanged: try { // Get the object for the selected department. Department department = (Department)this.departmentList.SelectedItem; // Bind the grid view to the collection of Course objects // that are related to the selected Department object. courseGridView.DataSource = department.Courses; // Hide the columns that are bound to the navigation properties on Course. courseGridView.Columns["Department"].Visible = false; courseGridView.Columns["StudentGrades"].Visible = false; courseGridView.Columns["OnlineCourse"].Visible = false; courseGridView.Columns["OnsiteCourse"].Visible = false; courseGridView.Columns["People"].Visible = false; courseGridView.Columns["DepartmentId"].Visible = false; courseGridView.AllowUserToDeleteRows = false; courseGridView.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells); } catch (Exception ex) { MessageBox.Show(ex.Message); }
Task 5: inserting and updating data Save changes to object data made by using data controls to the School database. closeForm_Click: // Dispose the object context. schoolContext.Dispose();
saveChanges_Click: try { // Save object changes to the database, // display a message, and refresh the form. schoolContext.SaveChanges(); MessageBox.Show("Changes saved to the database."); this.Refresh(); } catch(Exception ex) { MessageBox.Show(ex.Message); }
Lazy loading // First, using LINQ to SQL: L2SDataContext dc = new L2SDataContext(); this.DataGrid1.DataSource = dc.Customers.First().Orders; // => 3 records in the data grid this.DataGrid1.DataBind();
// Using the Entity Framework: EFEntities efc = new EFEntities(); this.DataGrid2.DataSource = efc.Customers.First().Orders; // => 0 records in the data grid! this.DataGrid2.DataBind();
LINQ to SQL automatically went back to the database and loaded the orders for that first customer. The team behind EF didn't want this automatic behavior happening: when architecting a larger project, it is highly important for developers to clearly understand when they are accessing certain resources, such as the database.
// Explicitly include the orders from the database in one shot: this.DataGrid2.DataSource = efc.Customers.Include("Orders").First ().Orders; // OR // Explicitly load the orders after retrieving the customer: var customer = efc.Customers.First(); customer.Orders.Load(); this.DataGrid2.DataSource = customer.Orders;
m/EFLazyLoading
m/EFDocSamples2008 (HRSkillsCombined.zip)
Good luck, and keep in touch!