The information in this post is out of date.

Visit msdn.com/data/ef for the latest information on current and past releases of EF.


 

Building applications that work across tiers is a core part of many application architectures. In .NET Framework 3.5 SP1 we provided basic functionality that enabled developers to serialize and de-serialize entities. However, the experience in the first version had limitations which required developers to do a non-trivial amount of work. As Alex very aptly puts it in his blog post, N-Tier development is not about transferring state between client and server. Indeed, that is the easy part! What you actually need is to:

  1. Infer what the state changes are that need to be applied from a disconnected graph.
  2. Communicate those changes to the persistence layer.

The API in the first version was designed to track changes on an object graph made of entities that notify state changes on them and then commit those changes to the database. However, once multiple changes have happened outside the reach of the state manager (i.e. on a different tier), it becomes very difficult to reflect them back in the state manager.

To address this problem, in .NET 4.0 we first added new lower level APIs that can be used to tell the state manager directly what changes need to be applied. The most representative methods in the new API are:

  • ObjectContext.ApplyOriginalValues
  • ObjectStateManager.ChangeObjectState
  • ObjectStateManager.ChangeRelationshipsState

Those APIs could be easily put to use, for instance, by customers that create their own Data Transfer Objects to do N-Tier development.

When we described these API’s on the EF Design blog, your feedback was that we needed to provide developers more of an end-to-end N-Tier experience on top of Entity Framework. Therefore we went back to work on figuring out how to not only enable the myriad of possible N-Tier approaches on top of the new API, but also which approaches we could actually implement and own.

One of these approaches, that seem to provide the most benefits, is to create entity classes that store just enough information about state changes within themselves. We discussed this approach of Self-Tracking Entities here. We are shipping a T4 template (not included in Beta 1 but will be available shortly after that; stay tuned for details) that can generate a set of classes and a set of extension methods for ObjectContext.

Here is a sneak peek of what is possible with self tracking entities:

// Service-side code
public 

Order

 GetOrder(int orderID)
{
    using(var context = new 

OrderEntities

())
    {
        return context.Orders.Include("Lines")
            .Where(it => it.OrderID == orderID)
            .FirstOrDefault();
    }
}

public void ApplyChangesToOrders(

Order

 order)
{
    using(var context = new 

OrderEntities

())
    {
        context.Orders.ApplyChanges(order);
        ValidateChanges(context);
        context.SaveChanges();
    }
}

// Client-side code
public void ApplyDiscountOnClient(int orderID, decimal percentage)
{
    using(var client = new 

OrdersServiceClient

())
    {
        

Order

 order = client.GetOrder(orderID);
        foreach(var line in order.Lines)
        {
            line.PercentageDiscounted = percentage;
        }
        client.ApplyChangesToOrders(order);
    }
}

Notice that in this code, the ApplyChanges extension method will extract change information from the graph of self tracking entities that was modified on the client, and using the low level N-Tier API will reflect those changes in the ObjectStateManager so that they can be later saved to the database.

Keep monitoring the ADO.NET Team blog as we’ll be posting more in depth blogs on N-Tier and Self-Tracking Entities.

Thanks,

Diego Vega
Program Manager ADO.NET Entity Framework