Webinar: Real-World Entity Framework

UPDATE: The screencast video is now available to be streamed or downloaded.

I just delivered a screencast for DevelopMentor on Entity Framwork Real World topics – Transactions, Concurrency, Stored Procedures.  A recording of the screencast will soon be available, but you can download the slides and code here.  Enjoy.

Posted in Technical | Leave a comment

Trackable DTO’s: Taking N-Tier a Step Further with EF4

UPDATE: I created a new version of the client-side T4 template for generating trackable DTO’s.  This completely decouples the client from the service by producing POCO classes based on the service metadata, instead of on the entity data model used by the service.  I have also updated the client T4 template to accept a max received message size parameter.

WEBINAR: On March 30, 2010, I conducted an online seminar on Trackable DTOs.  The screencast video is now available to be streamed or downloaded.  The slides and code for the presentation are also available.

Download updated code for this post here.

Not long ago my friend and colleague Richard Blewett wrote a blog post on Self-Tracking Entities in EF4, in which he questioned the service-orientation of Self-Tracking Entities in EF4.  While STE’s are placed in an assembly that does not reference the Entity Framework, the way in which change state is preserved in an STE is overly complex because it tries make it easier for EF to transmit those changes to the ObjectStateManager on the service side.  If you look closely at the ObjectChangeTracker class that is generated for the client, you’ll see that it maintains metadata for navigation properties with items that have been added or removed, as well as original values and extended properties.  Requiring a Java client to implement all that is asking an awful lot, and it couples the client too tightly to the service implementation.

About a year ago I wrote an article for MSDN Magazine on how to track change-state on the client and transmit it to a service for persistence using LINQ to SQL, Entity Framework, or some other data access stack.  Each entity has an ObjectState property indicating its change state (Unchanged, Added, Modified, Deleted), which is sent to the service where it is used to perform inserts, updates and deletes against a database.  The beauty of this approach is that it allows multiple changes to be sent to a service in a single round trip, where they can all be saved in a single transaction.  The classic example of this is an Order with Order Details that have been added, modified or removed.  An UpdateOrder method in the Data Access Layer can simply read the ObjectState property to perform corresponding inserts, updates and deletes.

Fast forward to Entity Framework 4.0 and Visual Studio 2010.  This week I implemented Trackable Data Transfer Objects with EF4 using the same basic architecture that I wrote about in the article.  I use two sets of T4 templates (a code-generation technology built into Visual Studio):  One set is used by the Data Access Layer on the service side to generate both the ObjectContext container class and POCO classes that serve as DTO’s but have an ObjectState property.  On the client side there is an assembly containing another T4 template that generates DTO’s that also have an ObjectState property.  On the client-side, DTO’s have a Tracking property (to turn change-tracking on and off) and navigation properties that are of type ChangeTrackingCollection<T>.  This collection is placed in a separate ClientChangeTracker assembly and marks entities as Modified when they change, or as Added or Deleted when they are added to the collection or removed from it.

The goal of this design is to keep change state as minimal as possible: a simple ObjectState enum, which is exposed as a data contract by the service and can be easily implemented by a non-.NET client.  The client-side DTO’s are generated by a T4 template that consumes the service metadata, which results in a clean separation between the client and any persistence concerns (see UPDATE section above).

On the service-side there is a ServiceChangeTracker assembly that has a TrackingHelper class with an ApplyChanges methods that extends ObjectContext by walking an object graph and informing the ObjectStateManager of entity state based on the ObjectState property.  When a DAL method invokes SaveChanges on the ObjectContext, inserts, updates and deletes are persisted to the database in the scope of a single transaction.  The DAL can then call AcceptChanges in TrackingHelper to restore objects to an Unchanged state and return the updated object to the client with database-calculated values, such as identity and concurrency fields.

Trackable DTO’s match entities defined in the conceptual model, which allows us to leverage POCO support in EF4 to avoid creating two sets of classes and manually copying data between them.  As such they represent an approach that combines the simplicity of self-tracking entities with the flexibility of DTO’s, without the extra baggage and complexity of STE’s.  The use of two separate sets of T4 templates allows us to decouple client DTO’s from the service DTO’s, applying the rules of data contract versioning so that they can diverge from one another in a robust fashion.

Enjoy.

Posted in Technical | 35 Comments

EF4 compared to NHibernate

Last week while teaching my new LINQ and Entity Framework course I got a question asking me to compare EF4 with NHibernate.  Not having worked extensively with NHibernate, I wasn’t in a position to address the question.  Then yesterday I received an email containing a link to a blog post by Oren Eini (aka Ayende Rahien) doing just such a comparison.  Because Ayende comes from the NHibernate camp, I thought it would be interesting to highlight some EF4 capabilities lacking in the current version of NHibernate.

  1. EF is more than an ORM and supports a streaming model with data readers against the entity model without materializing entities
  2. EF supports LINQ out of the box (NH doesn’t have it yet)
  3. EF has a good designer (NH doesn’t)
  4. EF has much better documentation
  5. EF has an end-to-end n-tier solution out of the box with Self-Tracking Entities (nothing like that for NH)
  6. WCF Data Services (Astoria) integrates well with EF

On the other side, NH is a much a more mature ORM product than EF and has better batching capabilities.  It is also more extensible, especially as an open-source product.  That said, EF also has extensibility points, as evidenced by the EF Extensions project, which enables processing of multiple result sets from stored procedures.  EF also allows you to define functions with Entity SQL that are embedded in the entity model, and you can execute queries and commands directly against the database, effectively doing an end-run around EF while mapping the results to entities.

Ayende mentions that NH will add LINQ with version 3.0, as well as better documentation, and I’m confident that EF will fold in features from NH in future releases.  The end result will be greater parity between the two products going forward, making the choice even more challenging and determined mostly by philosophical and strategic factors.

Posted in Technical | 17 Comments

100 EF4 Links

As part of my DevelopMentor Entity Framework course, I put together a delicious web site containing over 100 links to Entity Framework 4.0 topics.

http://delicious.com/tonysneed_elinq

Enjoy.

Posted in Technical | Leave a comment

ELINQ with EF 4.0 Course Update

I’ve been working feverishly the last couple of months to update my DevelopMentor course: Essential LINQ with Entity Framework 4.0.  Here is a breakdown of the course content:

Day 1:

1. Functional Programming in C#
2. LINQ to Objects
3. LINQ to XML

Day 2:

4. LINQ to SQL
5. EF: Architecture
6. EF: LINQ to Entities

Day 3:

7. EF: Real-World Topics
   – Transactions, Concurrency, Stored Procedures
8. EF: N-Tier Applications
9. EF: Mapping Scenarios

Day 4:

10. EF: Development Approaches:
       – Patterns, TDD, Model-First
11. ADO.NET Data Services

Here’s when and where we’re offering the course:

Boston: February 9-12, 2010
London: February 23-26, 2010
Los Angeles: March 30-April 2, 2010
Boston: April 20-23, 2010
London: May 4-7, 2010
Los Angeles: June 8-11, 2010
Boston: June 29-July 2, 2010

Hope to see you in one of my classes sometime!

Cheers,
Tony

Posted in Technical | 2 Comments

Faking Enums in Entity Framework 4.0

I ran across a great post from Alex James on how to fake enums in EF4.  I’ve had a great deal of experience using enums with LINQ to SQL (via Plinqo), and it’s nice to know how to do it in EF, while waiting for the feature to come out-of-the-box in a future version. 😉

http://blogs.msdn.com/alexj/archive/2009/06/05/tip-23-how-to-fake-enums-in-ef-4.aspx

Enjoy.

Posted in Technical | Leave a comment

Adding Your Own T4 Templates for EF4 to Visual Studio 2010

I’ve been missing the T4 template for POCO classes that shipped with CTP 1 of Entity Framework 4.0 but was absent from CTP 2.  So I wanted to create my own and have it available in Visual Studio when selecting “Add Code Generation Artifact” from the context menu after right-clicking on the design surface of an EDMX file.

I posted a question to the EF4 Forum and was pointed to a link stating that the template name has to start with the string “ADONETArtifactGenerator_”.  Armed with this information, I simply copied the installed template for self-tracking entities and replaced the .tt files with those of the POCO template from CTP 1.  The VS item template zip file is located here, along with a bat file that copies them to the appropriate directories and installs them into Visual Studio.  Enjoy.

Posted in Technical | 5 Comments

Learn What’s New in Entity Framework 4.0!

I’ll be presenting a free DevelopMentor web cast on Tuesday Dec 8, 2009 at 9:00 am (Pacific Standard Time) on new features in Entity Framework 4.0.  There’s way too much that’s new to cover in a 90 minute web cast, but we’ll be focusing on the biggies:

  • POCO Classes
  • T4 Code-Generation Templates
  • Lazy Loading
  • Change-Tracking Options
  • Model-First and Code-Only Approaches
  • N-Tier Support

The web cast includes slides and demos , as well as question-and-answer periods in which we’ll discuss some of the other new features coming in Entity Framework 4.0.  To sign up, register here:

http://bit.ly/entityframework4

For a little background on myself, here’s my bio. If you would like to get a complete in-depth treatment of everything Entity Framework has to offer, sign up for my DevelopMentor course, Essential LINQ with Entity Framework 4.0, running in Los Angeles, Boston and London.  The course also includes coverage of LINQ (Objects, XML, SQL) and ADO.NET Data Services.

Update: Here are links to the recorded session: stream video, download video.

Posted in Technical | 1 Comment

So Cal Code Camp Session on Entity Framework 4.0

I’ll be presenting a session at Southern California Code Camp entitled “What’s New in Entity Framework 4.0” on Sunday Nov 22nd.

I gave the talk yesterday at the conference, which took place at USC.  The room was filled to capacity and about 25 more people tried to get in but couldn’t!  Had a great time, but I wish I had two hours to present instead of just one – so much to talk about. :)  Here are slides and demos from the talk, which I am going to present again as a DevelopMentor webinar on Dec 8th.

Update: I have updated the demos to cover POCO, T4 Templates, Loading Options, Change-Tracking, Model-First, Code-Only, and N-Tier.

Posted in Technical | Tagged | 4 Comments

EF 4.0 N-Tier Support: Take 2

Following the release of Visual Studio 2010 and .NET 4.0 Beta 2, the Entity Framework team put out a second CTP for Entity Framework 4.0, which includes enhancements to self-tracking entities. As the name implies, self-tracking entities know how to track their own state, so that it can be transmitted across service boundaries in an n-tier application. The idea is similar to what we’ve been able to do for several years with datasets. Datasets know how to keep track of their change-state and the table adapter knows how to inspect a dataset to generate insert, update and delete statements. However, because datasets are a .NET-specific type, it is not appropriate to expose them from services that should be platform-neutral. What we need is a service-oriented successor to the dataset that knows how to keep track of changes while remaining ignorant of how those changes will be persisted.

About a year ago I wrote an article for MSDN Magazine outlining one possible solution to this problem. Basically, I proposed attaching a property to each entity indicating its change-state (added, modified, deleted), and I supplied a custom collection capable of setting each entity’s change-state whenever it is added, modified or deleted. On the service-side, I wrote a helper class which interrogated entities for changes and persisted changes to the database, using either LINQ to SQL or the Entity Framework.

Entity Framework 4.0 uses the same basic approach, with entities tracking their own state and helper classes for change-tracking and persistence. The difference is that EF uses code-generation via T4 templates to create the helper classes instead of incorporating them into assemblies for the client and service to reference. I have to say that, although they could have built a client-side assembly without any dependencies on the Entity Framework, I have grown to like the code-gen approach. The reason is that T4 templates are totally open-source. If I don’t like what they did or want to change it in any way, all I have to do is create my own version of the template.

Lately I’ve had the chance to take STEs for a test drive, and I’ve put together a walk-through using the CTP 2 bits. You can download the sample application I created here. For convenience I’m using the Northwind sample database.

1. Open the Server Explorer in Visual Studio 2010 and a data connection to the Northwind database.

  • You may need to attach Northwind to SQL Express using Management Studio.
  • You may wish to add a RowVersion column of type timestamp to each table to facilitate concurrency management.

2. Create a class library project using Visual Studio 2010 and name it NorthwindData.

  • Add a new item to the project, selecting "ADO.NET Entity Data Model," naming it Northwind.edmx.
  • Select "Generate from Database" and choose the following tables:
    Customers, Orders, Order_Details, Products, Categories

3. Right-click on the model design surface and select "Add Code Generation Item."

  • Under the Code category select "ADO.NET Self-Tracking Entities" and name the T4 template Northwind.tt.

4. Add another class library project to the solution and name it NorthwindModel

  • Move the Northwind.Types.tt template to the NorthwindModel project.
  • Add a reference to System.Runtime.Serialization.
  • Add a project reference for NorthwindModel in NorthwindData project.
  • Open Northwind.Types.tt and modify inputFile initialization as follows:
    string inputFile = @"..\NorthwindData\Northwind.edmx";
  • Open Northwind.Context.tt and add "using NorthwindModel" directive in two places, both following <auto-generated> comment sections.

5. Add a WCF service to the solution (this can be a console app).

  • Reference both NorthwindData and NorthwindModel projects.
  • Add an interface called INorthwindService with a [ServiceContract] attribute and add methods with [OperationContract] attributes:
[ServiceContract]
public interface INorthwindService
{
    [OperationContract]
    Product GetProduct(int productId);

    [OperationContract]
    Order GetOrder(int orderId);

    [OperationContract]
    Order SaveOrder(Order order);

    [OperationContract]
    void DeleteOrder(Order order);
}

6. The GetOrder methods should use the Include operator to eager-load order details and products.

public Order GetOrder(int orderId)
{
    using (NorthwindEntities ctx = new NorthwindEntities())
    {
        // Eager-load related entities
        var query =
            from o in ctx.Orders
                .Include("OrderDetails.Product")
            where o.OrderID == orderId
            select o;
        Order order = query.SingleOrDefault();
        return order;
    }
}

7. In the SaveOrder method call ApplyChanges on ctx.Orders, passing the incoming Order entity (inserts and updates).

  • After calling ctx.SaveChanges, you will need to call AcceptChanges on both the order and each OrderDetail.
  • It would be nice if calling AcceptChanges on an order would in turn call AcceptChanges on items in collection properties.
  • The method should return the order that was saved in order to provide database-generated values (such as identity and concurrency fields).
  • For convenience, it would be nice to have a HasChanges extension method for IObjectWithChangeTracker that checks to see if items in collection properties have been modified, added or removed.
public Order SaveOrder(Order order)
{
    using (NorthwindEntities ctx = new NorthwindEntities())
    {
        // Inform object state mgr of changes
        ctx.Orders.ApplyChanges(order);

        // Persist changes to database
        ctx.SaveChanges();

        // Accept changes for order and details
        order.AcceptChanges();
        foreach (OrderDetail od in order.OrderDetails)
            od.AcceptChanges();
        return order;
    }
}

8. In the DeleteOrder method mark order and order details as deleted, then call ApplyChanges.

  • You will need to call ToList() on order.OrderDetails and then iterate the results to mark each item as deleted, so as not to modify the property during iteration. Then mark the order as deleted.
  • It would be nice if marking an order as deleted would also mark order details as deleted.
public static void DeleteOrder(Order order)
{
    using (NorthwindEntities ctx = new NorthwindEntities
        (Settings.Default.NorthwindConnection))
    {
        // First mark details as deleted (from a list)
        foreach (OrderDetail od in order.OrderDetails.ToList())
        {
            od.MarkAsDeleted();
        }

        // Then mark order as deleted
        order.MarkAsDeleted();

        // Inform object state mgr of changes
        ctx.Orders.ApplyChanges(order);

        // Persist changes to database
        ctx.SaveChanges();
    }
}

9. Add a client application to the project.

  • First reference the NorthwindModel project, then add a service reference to the WCF service. This will ensure that classes generated from the STE T4 template will be used.
  • Write code that creates a new order with two order details; change the order by adding a new detail, changing an existing detail, and removing a detail; then delete the entire order.
  • It would be nice to have a GetChanges methods that obtains only items that have been added, modified or deleted, so that it is not necessary to send unchanged items to the service for updating.

10. In order to delete an order detail, it is not sufficient to simply remove it from the order. Rather, you will need to call MarkAsDeleted on the order detail.

  • This behavior appears to be a bug, because removing an item from a collection should automatically mark it as deleted, just as adding or modifying an item automatically marks it as added or modified.

If you experimented with self-tracking entities in the first EF 4.0 CTP, based on Beta 1 of .NET 4.0 and Visual Studio 2010, you may have noticed a different method signature for ApplyChanges, in which you had to pass a delegate the returned an EntityChangeTrackerAdapter. While allowed you to supply your own adapter for converting change-state, the method signature for ApplyChanges is simpler and easier to use.

CTP 2 also improved the story of self-tracking entities by taking code for relationship fix-up out of the collection and placing it in the generated entity classes, where it takes advantage of the foreign key associations. The T4 templates for STEs also provide better support for concurrency management by preserving original values for properties that specify a ConcurrencyMode of Fixed in the entity data model. And the AcceptChanges method makes it easier to reinitialize an entity to an unmodified state after it’s been updated.

Hats off to the EF team for tackling n-tier scenarios head-on and coming up with an end-to-end solution for using the Entity Framework in service-oriented applications. Keep up the good work!

Posted in Technical | 18 Comments