Using EF DbContext with WCF Data Services

December 11, 2010

Using EF DbContext with WCF Data Services

One of the questions that you may ask yourself with the new EF feature CTP5 is how Using DbContext with WCF Data Servicesto embed the new DbContext object inside an OData service or more particularly inside WCF Data Service. This post will supply the solution.

DbContext as WCF Data Service Data Source

Entity Framework has a good integration with WCF Data Services. All you need to do when you create a WCF Data Service with EF is to put the generated ObjectContext as a data source of the service. The following code is a simple WCF Data Service on top of EF ObjectContext:

public class SchoolDataService : DataService<SchoolEntities>
{
  public static void InitializeService(DataServiceConfiguration config)
  {
    config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
 
    config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
  }
}

When you will try to do the same with DbContext you will get a surprise. The service will run but when you will try to query the data it expose you will get an error like the following:

The XML page cannot be displayed 
Cannot view XML input using XSL style sheet. Please correct the error and then click the Refresh button, or try again later. 
 
 
--------------------------------------------------------------------------------
 
The following tags were not closed: feed. Error processing resource 'http://localhost:29753/SchoolDataService.svc/Courses'. 
 
 

The reason for the error is because currently DbContext and WCF Data Services integration isn’t working well. So what can we do for now?

Since the DbContext is a wrapper for the ObjectContext we can expose the ObjectContext itself. In order to do that you will have to override the CreateDataSource method of the service and return the ObjectContext. The following example shows a simple WCF Data Service that uses the DbContext I’ve created in the previous post about EF Feature CTP fluent API:

[ServiceBehavior(IncludeExceptionDetailInFaults=true)]
public class SchoolDataService : DataService<ObjectContext>
{
  public static void InitializeService(DataServiceConfiguration config)
  {
    config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
 
    config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
  }
 
  protected override ObjectContext CreateDataSource()
  {     
    var context = ((IObjectContextAdapter)new SchoolEntities()).ObjectContext;      
    context.ContextOptions.ProxyCreationEnabled = false;      
    return context;    
  }    
}

A few things to notice:

  • In the CreateDataSource I cast the DbContext to an interface it implements – IObjectContextAdapter. This interface exposes an ObjectContext property which is the underling context wrapped by the DbContext.
  • You must disable proxy creation because in service scenarios you mustn’t use the change tracking and lazy loading behaviors that are created through runtime proxies.

Summary

DbContext integration with WCF Data Services isn’t supported currently. In order to have a working workaround for that you can use the underling ObjectContext which the DbContext wrap. Hopefully that in the near future this workaround won’t be needed and we will have integration out of the box.

Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>