Feeds:
Posts
Comments

I recently delivered a free webinar for DevelopMentor on n-tier application development using Entity Framework 4.0.  In it I explained how to use what I call “Trackable Data Transfer Objects” to achieve the same result as “Self-Tracking Entities” but using a more lightweight tracking mechanism to achieve better interoperability, as I outlined in this blog post.

The screencast video is now available to be streamed or downloaded.  The slides and code for the presentation are also available.

O’Reilly has a program that provides online access to books that have yet to be published.  It’s called “Rough Cuts” and allows you to read chapters as they are written but before they are cleaned up for final publication, and it provides a discounted price for online and print editions.  Given the nature of technology and the speed of change, I find early access to be quite valuable.   Here are two books listed that I recommend ordering in their Rough Cuts version:

Programming Entity Framework Second Edition by Julia Lerman.  This includes coverage of Entity Framework 4.0 with samples in C#.

Programming WCF Services Third Edition by Juval Lowy, which covers new features in .NET 4.0.

Someone recently asked me this question:  When a company that has been using 2 tiers wants to move to n-tier, what are the considerations for choosing WCF and STEs [or Trackable DTOs] vs. WCF Data Services?

This is a great question because it relates to a recent re-alignment of what used to be called “ADO.NET Data Services” (code-named Astoria) under the umbrella of Windows Communication Foundation (WCF), as well as the renaming of .NET RIA Services to WCF RIA Services.  I’m going to steal an image from the .NET Endpoint blog, because it shows how each programming model rests on top of the infrastructure provided by WCF.

image

The two bottom layers should be quite familiar to anyone who uses WCF, but the diagram could mistakenly lead you to the conclusion that the programming model section is independent of the underlying Service Model and Channel layers.  The truth is that RIA Services rests on Data Services, which is turn sits on top of Web HTTP Services (aka REST), which is tightly coupled to HTTP as a transport and XML, Atom or Json as a format.  Only SOAP Services (leaving Workflow Services aside for the moment) can be used with any format and transport protocol.

Practically speaking, what this means is that there is a fork in the road when it comes to deciding how to implement an n-tier application architecture.  WCF SOAP Services (that is, traditional WCF) offers the most flexibility when it comes to selecting an underlying transport.  For example, I may want to use a NetMsmqBinding with clients and services that are occasionally connected.  The other way to go is to select a REST-based programming model, which leverages the universality of the HTTP protocol and uses a URI addressing scheme.  If flexibility concerning the transport layer matters to you, then traditional SOAP-based WCF services are the way to go.

Another differentiating factor is that WCF SOAP Services tend to be operation-based, while REST services are said to be resource-based.  That means clients are effectively going to call methods on a SOAP service, while client of a REST service are going to send HTTP requests (mostly GET’s) to a URI and expect to get some resource in return, usually a blob of XML, probably in a syndication feed format such as ATOM.  From an architectural perspective what this means is that service operations will be inherently more constrained than resources that are freely accessible.  Whether that’s good or bad depends entirely on your point of view.  If you want to design a service that is more tightly locked down, then you’ll most likely prefer a traditional WCF service.  On the other hand, if you want to freely make your data available to clients (especially clients that may not understand or care about SOAP), you would get more bang for your buck with a REST-based service.

Traditional WCF services are also going to allow you a more advanced level of security (for example, message-based or federated security), and can offer reliable messaging and transactional services.  That’s because WCF supports the WS-* SOAP protocols that have evolved over the last several years.  On the other hand, you may not need or want any of those features.  If your client is mainly an AJAX web app, or even a Silverlight rich Internet app, then REST-based services are all you need, and you can benefit from tight coupling with HTTP.

From reading this post so far, you might get the impression that I favor traditional WCF services over REST-based services.  And if we were only talking about a service programming model, you might be right.  But Microsoft has done a lot of work on the client-side programming model for Data Services.  All you have to do for a .NET client is simply write a LINQ query, and Data Services will translate it to a URI sent to the service.  The resulting XML is used to populate client-side entities, which are change-tracked.  Heck, it even supports batch updating and concurrency control. Sweet.  And WCF RIA Services strives for RAD n-tier development for Silverlight apps, with support for end-to-end data validation and a whole bunch of other goodies.  In addition, these higher-order programming models allow you to blend in an operation-based approach by adding methods to your data service.

So I suppose your choice between SOAP and REST services will depend a great deal on the architectural objectives dictated by your application requirements.  Alas, there’s still a role for the architect in all of this. :)

Additional Resources:
White Paper on RESTful Web Services with WCF 3.5
Scott Hanselman Interview with Pabro Castro on OData
Open Data Protocol (OData)
WCF Data Services Team Blog
Entity Framework 4.0 and WCF Data Services 4.0 in Visual Studio 2010

I’m a self-admitted control-freak.  And when I add a service reference to a project pointing to a WCF service that exposes metadata, I would like more control over the code-generation process.  Not long ago I had a specific need to to this when creating a client-side T4 template for my Trackable DTO’s project with Entity Framework 4.0.  Instead of relying solely on “Add Service Reference” in Visual Studio to generate client-side POCO classes, I wanted to generate the classes myself, hooking into a change-tracking mechanism and injecting data binding code.

The way that Self-Tracking Entities in EF4 accomplishes this is to add a class library project with a T4 template the inspects an entity data model (edmx file).  The problem is that this class library assembly must then be referenced both by the service and the client, violating a tenet of service-oriented applications to share contract and schema but not class or assembly.  That way, the client could be completely ignorant of the persistence stack used (in this case Entity Framework), and there could be a cleaner separation of concerns.  The WCF service could use a data access layer (DAL) to abstract away persistence concerns, and the client could make use of a change-tracker that the service would have no interest in referencing.

And so I needed to generate client-side entities with data contracts using a T4 template that could read service metadata exposed as WSDL.  The way to do this would be to create a WsdlImporter referencing data contracts from a service.  The result would be a CodeCompileUnit, which I could reflect over using the CodeDom to generate class and member definitions.

private CodeCompileUnit GetMetadataCodeUnit(string mexAddress,
    long maxReceivedMessageSize, Type collectionType)
{
    Binding mexBinding = GetMetadataBinding(mexAddress,
        maxReceivedMessageSize);
    var mexClient = new MetadataExchangeClient(mexBinding);
    mexClient.ResolveMetadataReferences = true;

    var metadata = mexClient.GetMetadata
        (new EndpointAddress(mexAddress));
    var sections = metadata.MetadataSections
        .Where(s => s.Identifier.Contains("datacontract.org"));
    var metaDocs = new MetadataSet(sections);
    var wsdlImporter = new WsdlImporter(metaDocs);

    var schemaImporter = new XsdDataContractImporter();
    schemaImporter.Options = new ImportOptions();
    schemaImporter.Options.ReferencedCollectionTypes
        .Add(collectionType);
    schemaImporter.Import(wsdlImporter.XmlSchemas);
    return schemaImporter.CodeCompileUnit;
}

The GetMetadataBinding method creates a custom binding with a transport element that has been configured with the specified max received message size.

private Binding GetMetadataBinding(string mexAddress,
    long maxReceivedMessageSize)
{
    Uri uri = new Uri(mexAddress);
    BindingElement element = null;
    switch (uri.Scheme)
    {
        case "net.pipe":
            element = new NamedPipeTransportBindingElement();
            ((NamedPipeTransportBindingElement)element)
              .MaxReceivedMessageSize = maxReceivedMessageSize;
            break;
        case "net.tcp":
            element = new TcpTransportBindingElement();
            ((TcpTransportBindingElement)element)
              .MaxReceivedMessageSize = maxReceivedMessageSize;
            break;
        case "http":
            element = new HttpTransportBindingElement();
            ((HttpTransportBindingElement)element)
              .MaxReceivedMessageSize = maxReceivedMessageSize;
            break;
        case "https":
            element = new HttpsTransportBindingElement();
            ((HttpsTransportBindingElement)element)
              .MaxReceivedMessageSize = maxReceivedMessageSize;
            break;
        default:
            break;
    }
    if (element != null)
    {
        Binding binding = new CustomBinding(element);
        return binding;
    }
    else
    {
        return null;
    }
}

Here is a link to a simple Console app that tests the WsdlImporter code.  And here is a link to a project that implements it as a T4 template.

Enjoy.

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.

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.

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.

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.

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

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.

Older Posts »