Click here to Skip to main content
15,867,568 members
Articles / Programming Languages / C#

Using EF DbContext with WCF Data Services

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
11 Dec 2010CPOL2 min read 28.9K   4   2
Using EF DbContext with WCF Data Services

Introduction

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 ObjectContexts a data source of the service. The following code is a simple WCF Data Service on top of EF ObjectContext

C#
public</span /> class</span /> SchoolDataService : DataService<SchoolEntities>
{
  public</span /> static</span /> void</span /> InitializeService(DataServiceConfiguration config)
  {
    config.SetEntitySetAccessRule("</span />*"</span />, 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 exposes, 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 DbContextnd WCF Data Services integration isn’t working well. So what can we do for now?
Since the DbContexts a wrapper for the ObjectContextwe can expose the ObjectContexttself. In order to do that, you will have to override the CreateDataSourceethod of the service and return the ObjectContextThe following example shows a simple WCF Data Service that uses the DbContext’ve created in the previous post about EF Feature CTP fluent API:

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

A few things to notice:

  • In the CreateDataSourceI cast the DbContexto an interface it implements – IObjectContextAdapterThis interface exposes an ObjectContextroperty which is the underlying 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

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


This article was originally posted at http://feeds.feedburner.com/GilFinkBlog

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Technical Lead sparXys
Israel Israel
Gil Fink is a web development expert and ASP.Net/IIS Microsoft MVP. He is the founder and owner of sparXys. He is currently consulting for various enterprises and companies, where he helps to develop Web and RIA-based solutions. He conducts lectures and workshops for individuals and enterprises who want to specialize in infrastructure and web development. He is also co-author of several Microsoft Official Courses (MOCs) and training kits, co-author of "Pro Single Page Application Development" book (Apress) and the founder of Front-End.IL Meetup. You can read his publications at his website: http://www.gilfink.net

Comments and Discussions

 
GeneralMy vote of 5 Pin
mohsenbz11-Apr-12 21:08
mohsenbz11-Apr-12 21:08 
GeneralCTP5&WCF Data Services don't mix well :( Pin
DotNetWise11-Dec-10 6:50
DotNetWise11-Dec-10 6:50 
I've just tried that and it works.
But if you try to do any $select=SomeProperty it crashes ugly with this error:
{
-error: {
code: ""
-message: {
lang: "en-GB"
value: "Not Implemented"
}
-innererror: {
message: "Unable to create a constant value of type 'System.Data.Services.Internal.ProjectedWrapper2'. Only primitive types ('such as Int32, String, and Guid') are supported in this context."
type: "System.NotSupportedException"
stacktrace: " at System.Data.Objects.ELinq.ExpressionConverter.ConstantTranslator.TypedTranslate(ExpressionConverter parent, ConstantExpression linq) at System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq) at System.Data.Objects.ELinq.ExpressionConverter.ConditionalTranslator.TypedTranslate(ExpressionConverter parent, ConditionalExpression linq) at System.Data.Objects.ELinq.ExpressionConverter.TranslateLambda(LambdaExpression lambda, DbExpression input) at System.Data.Objects.ELinq.ExpressionConverter.TranslateLambda(LambdaExpression lambda, DbExpression input, DbExpressionBinding& binding) at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SelectTranslator.Translate(ExpressionConverter parent, MethodCallExpression call) at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq) at System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq) at System.Data.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable`1 forMergeOption) at System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption) at System.Data.Objects.ObjectQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator() at System.Data.Entity.Infrastructure.DbQuery`1.System.Collections.IEnumerable.GetEnumerator() at System.Data.Services.Internal.ProjectedWrapper.EnumerableWrapper.GetEnumerator() at System.Data.Services.WebUtil.GetRequestEnumerator(IEnumerable enumerable)"
}
}
}

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.