Click to Rate and Give Feedback
Related Articles

This month we demonstrate how easy it is to use IronPython to test .NET-based libraries.

James McCaffrey

MSDN Magazine June 2009

...

Read more!

Developers frequently face issues related to scalability bottlenecks when they have applications that need to handle a lot of load. This article describes the role of a distributed cache in building scalable applications.

Iqbal Khan

MSDN Magazine July 2009

...

Read more!

We demonstrate creating a peer-to-peer processing platform where multiple players function together for a common purpose: getting your work done.

Matt Neely

MSDN Magazine June 2009

...

Read more!

We use the new Asynchronous Agents Library in Visual C++ 2010 to solve the classic Dining Philosophers concurrency problem.

Rick Molloy

MSDN Magazine June 2009

...

Read more!

In this article the author looks at two versions of the same application--one consuming an on-premise Data Service, and one consuming an Azure Table Data Service to illustrate data access in the cloud.

Elisa Flasko

MSDN Magazine May 2009

...

Read more!

Also by this Author

ADO.NET Data Services and Silverlight make a powerful combination, but to make them work well together, there are a few things you need to understand. Here, John Papa explains.

John Papa

MSDN Magazine April 2009

...

Read more!

This month John Papa fields some of his favorite questions regarding data manipulation with ADO.NET.

John Papa

MSDN Magazine January 2007

...

Read more!

Here John Papa demonstrates how to build a Silverlight 2 user interface that communicates through WCF to interact with business entities and a database.

John Papa

MSDN Magazine September 2008

...

Read more!

SQL Server Management Objects offer developers a robust toolset for backing up and restoring databases, and issuing DDL commands, as John Papa explains.

John Papa

MSDN Magazine June 2007

...

Read more!

Reporting has always been one of the dark arts of development. The tools typically seem to do just enough to get you to a certain point, then leave you to find workarounds to solve more complex issues.

John Papa

MSDN Magazine July 2006

...

Read more!

Popular Articles

Here we present techniques for programmatic and declarative data binding and display with Windows Presentation Foundation.

Josh Smith

MSDN Magazine July 2008

...

Read more!

This article introduces 10 development tools that can increase your productivity, give you a better understanding of .NET, and maybe even change the way that you develop applications. The tools covered include NUnit to write unit tests, Reflector to examine assemblies, FxCop to police your code, Regulator to build regular expressions, NDoc to create code documentation and five more.

James Avery

MSDN Magazine July 2004

...

Read more!

The MVP pattern helps you separate your logic and keep your UI layer free of clutter. This month learn how.

Jean-Paul Boodhoo

MSDN Magazine August 2006

...

Read more!

One-time passwords offer solutions to dictionary attacks, phishing, interception, and lots of other security breaches. Here's how it all works.

Dan Griffin

MSDN Magazine May 2008

...

Read more!

C# allows developers to embed XML comments into their source files-a useful facility, especially when more than one programmer is working on the same code. The C# parser can expand these XML tags to provide additional information and export them to an external document for further processing. This article shows how to use XML comments and explains the relevant tags. The author demonstrates how to set up your project to export your XML comments into convenient documentation for the benefit of other developers. He also shows how to use comments ...

Read more!

Data Points
The Entity Framework In Layered Architectures
John Papa

This column is based on a prerelease version of the ADO.NET EntityFramework. All information herein is subject to change.

Code download available at: DataPoints2008_07.exe (3,549 KB)
Browse the Code Online
When architects of an n-tiered architecture evaluate any new technology, pattern, or strategy, they have to consider how that new piece of the puzzle is going to mesh with the architecture. With the Entity Framework, integration is not a problem. It can be integrated into an n-tier architecture as well as a single-tier architecture.
In this month's column I will demonstrate how the Entity Framework can fit into an n-tier architecture that uses Windows® Communication Foundation (WCF) and Windows Presentation Foundation (WPF) technologies and the Model View Presenter (MVP) pattern. I will present a sample architecture that contains layers for a logical store database, data access, a domain model, a business manager, a service layer, a presentation layer, and a passive UI layer, and I will demonstrate how these layers integrate using the Entity Framework. All of the code examples I use are available for download from the MSDN® Magazine Web site.

Defining Layers
The application I'll present allows a user to search for customers in the NorthwindEF sample database and view, add, edit, or delete them. Before diving into the code and the examples, let's discuss the overall architecture of the sample. Because my focus is not the architecture itself, but how to integrate the Entity Framework with an architectural design, I chose a relatively common architecture that can be modified and integrated fairly easily with other strategies.
Figure 1 shows a high-level view of a typical layered architecture. The top two layers handle the user interface presentation and navigation using a UI layer and a presentation layer. The UI layer can be implemented in any one of a variety of technologies; however, for this column and its examples I will use WPF. The UI layer follows the MVP pattern with a passive view, which means that the views (the top UI layer) are managed and directed by the presentation layer. The presenters are responsible for giving the views their data, pulling data from the views to be saved in the lower layers, and in general for responding to events raised by the views.
Figure 1 Architectural Overview (Click the image for a larger view)
The presenters communicate with the lower tiers through WCF in my example here. A presenter will invoke a service through WCF using the service's contract as a guide. The service layer exposes its services through service contract interfaces. These contracts allow the presenters to be certain of how to call the services.
The service layer is responsible for receiving the communications from the presenters and calling the appropriate business layer methods that will execute appropriate business logic and data gathering or modifications. The business layer is where the business logic and the LINQ to Entities code for this project would reside. The LINQ to Entities code will reference the entity model that is generated from the Entity Framework. When the LINQ queries are executed, the Entity Framework will translate the LINQ query to the conceptual entity model (the Entity Data Model, or EDM), map the entity aspects to the storage layer, and generate a SQL query to execute against the database.

Building the Model
Now that I've provided a high-level overview of how the layers work in the architecture, let's examine the key aspects of each layer as they pertain to the Entity Framework. Since the database already exists for the application, I generated the entity model from the NorthwindEF database as a starting point.
I could have built the entity model first and then mapped the entities to the database as well. The EDM wizard helps generate the base entity model, which can then be modified as needed to incorporate inheritance, entity splitting, and other domain modeling concepts. Figure 2 shows the EDM wizard with all tables and stored procedures selected to be imported into the EDM.
Figure 2 Generating the Model from the Database (Click the image for a larger view)
One topic that often causes people confusion in regard to EDMs is the default naming convention for the EntitySets and the Entity­Types. I like to use singular names for all of my entities in my domain models. I create an instance of a Customer or return a list of Order instances using List<Order>. Each entity is a singular instance of a blueprint that has properties defining the entity.
On the other hand, I like my EntitySets to use a plural naming convention. The Entity­Sets are often used in LINQ queries when asking the ObjectContext to refer to its set of Customers or Orders.
As an example of this, take a look at the following LINQ to Entities query:
var q = from c in context.Customers
        select c;
List<Customer> customerList = q.ToList();
This query tells LINQ to Entities to access the Customers EntitySet and return all Customer entity instances when executed. The second line executes the query and returns the List<Customer> to the local variable named customerList. The EntitySet is plural in this example, making it clear that it is querying Entity­Sets and returning instances of the Customer (notice this is singular) entity.
Is it necessary to have this naming convention? Of course not. However, I find it helps make my code more readable. Otherwise, if you take the default of what is returned from the EDM wizard, you get an EntitySets named Customers and an EntityType named Customers, which makes your LINQ to Entities query look like this:
var q = from c in context.Customers
          select c;
  List<Customers> customerList = q.ToList();
When the EDM wizard generates the model, the EntitySet and EntityType names can easily be modified. This can be done by selecting the entity in the diagram, viewing its properties in the Properties window, and modifying the desired setting (see Figure 3). For this application, I modified all of the EntityTypes to be singular by setting the Name property. I did not change the EntitySet Name property, since it was already plural.
Figure 3 Changing the EntityType Names (Click the image for a larger view)

How It Works
Now I will demonstrate the application and discuss how it operates from the top layer down, starting with the views (located in the NWUI project) and the presenters (located in the NWPresentation project). Both projects are available in the code download that accompanies this column. The application loads a customer search view, which allows the user to search for customers by matching the company name criteria (see Figure 4). The view is implemented using WPF, and when a user interacts with the view it raises events that are listened to by its presenter, who can then take appropriate action.
Figure 4 Searching for Customers (Click the image for a larger view)
When the user searches for all customers starting with the letter D, as shown in Figure 4, the view raises an event when the user clicks the Search button. The presenter listens for this event and responds by calling the service layer through WCF to get the list of customer entities that will be displayed on the CustomerSearchView. Here is the code in the view when the user clicks the Search button:
private void btnSearch_Click(object sender,     RoutedEventArgs e)  {
      if (FindCustomerSearchResults != null)          FindCustomerSearchResults();
  }
This code does not interact with the list of entities that are returned, but, rather, it leaves that up to the presenter. The view uses WPF data binding to reference the entity's properties so it knows how to bind the list of entities to the list view control's elements. The only interaction the views have with the entities is through the data binding.
The CustomerSearchView raises the event FindCustomer­SearchResults, and the Customer­SearchPresenter listens for the event and responds by taking the baton and performing the search. The following code shows how the CustomerSearchPresenter class creates an instance of the NWServiceClient class, which is a proxy to the WCF service that is exposed on the lower tier:
public void view_FindCustomerSearchResults()
{
    if (this.view.CompanyNameCriteria.Length > 0)
        using (var svc = new NWServiceClient())
        {
            IList<Customer> customerList = svc.FindCustomerList(                view.CompanyNameCriteria);
            view.CustomerSearchResultsList = customerList;
        }
}
The NWServiceClient is referenced using a ServiceReference from the NWPresentation project so the presenters are aware of how to call the services and what types of data will be returned. The presentations layer does not and should not reference the EDM directly. Instead, it is told what types of entities to expect by the DataContracts exposed via WCF. This allows the Entity Framework's entities to be passed across a physical network boundary via WCF to the presenters.
Notice that once this list of Customer entities is returned, it is set to a public property on the view. This property of the view then accepts the List<Customer> and binds it to the DataContext of the view. The presenter serves up the data, passes it along, and the view handles any view-specific binding (since that code is very specific to the technology, whether it be WPF, Silverlight®, Windows Forms, or ASP.NET).
This technique allows the same presenter to be used to interact with any view that implements the ICustomerSearchView interface. In this application, the binding is handled by the WPF binding techniques using the DataContext.
The contracts expose the method that can be called in the service layer as well as the entities that will be returned. In this application, I only have a method to return the Customer and Order entity types. This means that only these entity types will be included in the contract.
WCF handles the serialization of the entities by applying the WCF DataContract attributes to them where needed. By exposing the entities through Data­Contracts the entities can be used in the UI layers without referencing the EDM directly.
Note that as of the .NET Framework 3.5 SP1 Beta 1, the Entity Framework supports automatic graph serialization. For example, if a parent entity has associated child entities, the parent and its child entities will be serialized. In the sample app, because the OrderManager's FindOrderList method uses a LINQ to Entities query that eager loads the Order Details for each Order, each Order entity returned from the middle tier will contain a List<OrderDetail> accessible through its navigation property.
While the serialized entities can be passed between the presenters and the service layer via WCF, the Object­Context is neither serialized nor passed to the presenter. This means the entities can be used in the UI layers but the Object­Context is left in the lower tiers where it will be able to access the EDM and the full resources of the Entity Framework.
Leaving the ObjectContext behind means that it can't be used to retrieve or modify entities in the UI layer directly, and it can't be used to manage change tracking in the UI layer. These roles are ideally left to the lower layers anyway. But when the entities are passed back down to the lower layers, the application has to synchronize with the ObjectContext so it can persist any changes in the entities.
When a user clicks the Search button shown in Figure 4, the presenter calls the service layer, which then calls the business layer (found in the NWBusinessManagers project) to retrieve the List<Customer>. This layer has two major roles. The first role is to get or put any data to or from the EDM. The second role is to handle any business logic that may exist.
The CustomerManager uses the ObjectContext to handle the interaction with the EDM, so it defines a local field called context and creates an instance of it in its constructor. The ObjectContext could be created and destroyed in each method. However, it is optimized to open and close database connection resources as needed. Also, by making the ObjectContext accessible throughout the class, it can maintain change tracking without having to be passed around a series of private methods within the class:
public CustomerManager()
{
    context = new NWEntities();
}
Note though that for this type of app, the Object­Context should not be held but created/destroyed as required. Due to identity resolution, holding on to the same object context will eventually lead to inconsistent, stale data and (as more and more data gets tracked) degraded performance when doing identity resolution, and it can lead to problems with updates in a multithreaded environment.
The following code shows the Customer­Manager class's Find­CustomerList method in the business layer. This method declares a LINQ to Entities query that accesses the context to request a list of Customer entities that start with the criteria. When this query is executed, it evaluates the mappings from the conceptual layer to the storage layer and generates an appropriate SELECT command:
public List<Customer> FindCustomerList(string companyName)
  {
      var q = from c in context.Customers
              where c.CompanyName.StartsWith(companyName)
              select c;
      return q.ToList();
  }
If you would like, you can view the queries as they execute using the SQL Server® Profiler.

Persisting Changes
Now that I have walked through the application using a simple retrieval, it is time to examine how modifications to data can be persisted. When a user edits a customer, the CustomerView view appears bound to the appropriate Customer entity instance (see Figure 5). The CustomerView raises an event to the presenter, who in turn requests the Customer entity instance from the lower layers.
Figure 5 Editing Customers (Click the image for a larger view)
When a user makes a modification to the customer and saves it, the entity is passed to the lower layers from the presenter using the code shown in Figure 6. This code evaluates whether the user was adding or modifying a customer and then calls the appropriate service layer method, passing the entity along for the ride.
public virtual void view_SaveCustomer()
{
    Customer customer = view.CurrentCustomer;
    var svc = new NWServiceClient();
    switch (view.Mode)
    {
        case ViewMode.EditMode:
            svc.UpdateCustomer(customer);
            break;
        case ViewMode.AddMode:
            svc.AddCustomer(customer);
            break;
        default:
            break;
    }
    view.CurrentCustomer = FindCustomer();

}
The service layer will then pass control on to the business layer, which will then save the customer entity to the database. Since the customer entity is no longer part of an ObjectContext, it must first be reunited with one by using the ObjectContext's Attach method, as shown in the code shown below. Once the entity has been attached to the context, the entity's properties must be marked as modified. This can be done by using the context's ObjectState­Manager and invoking the SetModified method for each property. Now that the context knows the entity is modified, the SaveChanges method can be issued, which will then generate a SQL UPDATE command and execute it against the database:
public void UpdateCustomer(Customer customer)
{
    context.Attach(customer);
    customer.SetAllModified(context);     // custom extension method
    context.SaveChanges();
}
Notice that the code in the UpdateCustomer method uses an extension method I named SetAllModified<T>, which makes it easier to set the state of all of the properties for an entity to be modified. SetAllModified<T> gets an instance of the ObjectStateEntry for the given entity T. It then retrieves a list of all of the property names for the entity and iteratively calls SetModifiedProperty for each property:
public static void SetAllModified<T>(this T entity, ObjectContext  context) 
where T : IEntityWithKey
{
    var stateEntry = context.ObjectStateManager.      GetObjectStateEntry(entity.EntityKey);
    var propertyNameList = stateEntry.CurrentValues.DataRecordInfo.      FieldMetadata.Select
      (pn => pn.FieldType.Name);
    foreach (var propName in propertyNameList)
        stateEntry.SetModifiedProperty(propName);
}
Another way to ultimately save the entity is to call the context's Refresh method. This tells the context to go get the data for the entity instance and refresh its property values from the database's values. The RefreshMode enumerator of ClientWins will replace the original values with the latest values from the database, thus allowing a last-in-wins strategy.
The RefreshMode of StoreWins will overwrite both original and current values in the entity cache with the values from the database. ClientWins is the appropriate strategy for last-in-wins, while StoreWins is an appropriate strategy when you want to cancel the changes and refresh the UI's view with the latest database values:
context.Refresh(RefreshMode.ClientWins, customer);  // Last in wins
The Entity Framework enforces optimistic concurrency when generating update and delete commands. It does this by including original values in the WHERE clause for any properties with a ConcurrencyMode attribute value set to Fixed.
By default, models are generated with no fields specified as concurrency fields. This means that when a user saves his changes, he possibly could be overwriting another user's changes inadvertently. If another user changes a value while the CustomerView is open and you want to use optimistic concurrency, you can do so by setting the ConcurrencyMode attribute of the EntityType in the conceptual model.
Editing the EDM file and setting the ConcurrencyMode to Fixed tells the Entity Framework to add this column to the WHERE clause of any Update or Delete commands. Thus, an OptimisticConcurrencyException is raised if a matching row is not found. Figure 7 shows this exception being raised when I modified the region of a customer in the database, just before the user tried to modify the same region.
Figure 7 OptimisticConcurrencyException (Click the image for a larger view)
You can trap this exception and take whatever action is appropriate. For example, you could trap the exception, log it, and then overwrite the user's changes anyway, as shown here:
catch (OptimisticConcurrencyException e){
    context.Refresh(RefreshMode.ClientWins, customer); // Last in wins
    logger.Write(e);
    context.SaveChanges();
}

Deleting and Adding
When a user deletes a customer, the CustomerManager's Delete­Customer method gets the customer entity and applies the delete:
context.Attach(customer);
context.DeleteObject(customer);
context.SaveChanges();
First, the Customer entity instance must be reunited with an Object­Context using the Attach method. Then the customer must be deleted from the ObjectContext. Done this way, the change tracking mechanism within the ObjectContext is aware the Customer entity instance has been deleted. Finally, when the SaveChanges method is called, the ObjectContext is now aware the entity was deleted and it should generate a DELETE SQL command and execute it.
When adding a customer, the CustomerManager's Add­Customer method gets the customer entity and applies the insert, like so:
context.AddToCustomers(customer);
context.SaveChanges();
This entity instance is new, so it must be added to the context and flagged as a new instance of a Customer entity by associating the Customer entity instance with an ObjectContext using the AddToCustomer method. Finally, when the SaveChanges method is called, the ObjectContext is aware that the entity was added and that it should generate an INSERT SQL command and execute it.

Wrapping It Up
Here I've demonstrated how the Entity Framework can integrate into an architecture, use modern patterns such as the MVP pattern, and handle the common architectural concerns. Key components of the Entity Framework in layered architectures are its change tracking mechanisms, integration with LINQ to Entities, ability to disconnect and reconnect with its ObjectContext, and how it provides a means for a developer to handle concurrency issues.

Send your questions and comments for John to mmdata@microsoft.com.

John Papa (johnpapa.net) is a Senior Consultant with ASPSOFT (aspsoft.com) and a baseball fan who spends summer nights rooting for the Yankees with his family. John, a C# MVP and INETA speaker, has authored several books and is now working on his latest, titled Data Access with Silverlight 2. He often speaks at conferences such as DevConnections and VSLive.


Page view tracker