EF CTP4 Tips & Tricks: WCF Data Service on DbContext
This is the fourth in a series of posts about the recently released Entity Framework Feature CTP4, now affectionately known as “EF Magic Unicorn Edition”.
For this post I’m going to assume you are somewhat familiar with the Productivity Improvements for EF and WCF Data Services.
You can download the completed VS2010 project from this post.
Update: If you want to use DbContext with Dynamic Data then you can use a similar approach as described in this post by Stephen Naughton.
Existing ObjectContext Experience
If you’ve used WCF Data Services on top of Entity Framework before then you would have added a new Entity Data Model to your project, which in turn creates a derived ObjectContext class to allow you to query and persist data using the model. Then you would have added a WCF Data Service class that derives from a DataService of your derived ObjectContext, something like this:
using System.Data.Services;
using System.Data.Services.Common;
namespace PI.WCFDataService.Sample
{
public class BlogService : DataService<BlogContext>
{
public static void InitializeService(DataServiceConfiguration config)
{
config.SetEntitySetAccessRule("Blogs", EntitySetRights.All);
config.SetEntitySetAccessRule("Posts", EntitySetRights.All);
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
}
}
}
What About DbContext?
Now what if your BlogContext derives from DbContext instead of ObjectContext? In the current CTP4 you can’t just create a DataService of a derived DbContext, although you can expect this to work by the time there is an RTM release.
But there is some good news, DbContext uses ObjectContext under the covers and you can get to the underlying context via a protected member. So lets define our derived context so that it exposes the context for our service to use:
using System.Data.Entity;
using System.Data.Objects;
namespace Service
{
public class BlogContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
public ObjectContext UnderlyingContext
{
get { return this.ObjectContext; }
}
}
}
Now all we need to do is create a DataService of ObjectContext and override the CreateDataSource method. In CreateDataSource we will construct a BlogContext and then return the underlying ObjectContext. Note that we also need to turn off proxy creation to allow WCF Data Services to function correctly.
using System.Data.Objects;
using System.Data.Services;
using System.Data.Services.Common;
namespace Service
{
public class BlogService : DataService<ObjectContext>
{
public static void InitializeService(DataServiceConfiguration config)
{
config.SetEntitySetAccessRule("BlogSet", EntitySetRights.All);
config.SetEntitySetAccessRule("PostSet", EntitySetRights.All);
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
}
protected override ObjectContext CreateDataSource()
{
var ctx = new BlogContext();
ctx.UnderlyingContext.ContextOptions.ProxyCreationEnabled = false;
return ctx.UnderlyingContext;
}
}
}
That’s it, now WCF Data Services just thinks it’s interacting with a standard ObjectContext and everything works.
Entity Set Naming
If you are using the Code First capabilities of DbContext then your entity set names will be <ClassName>Set. Obviously this isn’t brilliant and is something that will improve in future releases. The likely solution is to use the name of the DbSet property that you defined on the derived context.
Virtual SaveChanges
One thing to note with this approach is that WCF Data Services is going to call SaveChanges on the underlying ObjectContext and not your derived context. This is only an issue if you have overridden SaveChanges in your derived context to include business logic because this logic won’t get executed when the Data Service persists changes to the database. There isn’t a workaround for this at the moment but the issue will go away once there is native support for DbContext in WCF Data Services.
Summary
You can use DbContext with WCF Data Services, it’s not 100% natively supported just yet but will be in the future. The code to get it to work is pretty simple and makes use of the underlying ObjectContext from your derived DbContext.



Great post, Thanks!
Damien White
July 20, 2010
Awesome awesome awesome! Thanks for sharing this, I was totally scratching my head in what to do here
Phil Cockfield
July 20, 2010
Thanks so much for these non-obvious pointers!
I was wondering, does having to set the ‘ProxyCreationEnabled = false’ make using the DataService inefficient?
Is this something that is temporary for CTP, or a long term design feature?
Thanks!
Phil Cockfield
July 20, 2010
@Phil Cockfield
Switching off Proxy Creation is just a temporary thing as WCF Data Services doesn’t support EF proxies at the moment, this is something that will be supported in the future though.
The performance difference between proxies on/off will depend on the scenario but in most cases there should be very minimal difference.
romillerdotcom
July 23, 2010
Cool – thanks Ro.
Phil Cockfield
July 23, 2010
Fantastic. This is exactly the direction I’m going in.
Any ideas how to accomplish the same with RIA Services, instead of Data Services?
Andries
July 21, 2010
That makes GETs work just fine, but how about POST, PUT, and DELETEs. Attempting to perform a POST against the service yields:
The data source must implement IUpdatable or IDataServiceUpdateProvider to support updates
Damien White
July 21, 2010
I tried your example and it worked just fine.
My problem was that I was returning my context from CreateDataSource instead of the ObjectContext. Doing that works.
-Damien
Damien White
July 21, 2010
[...] Diego Vega posted on twitter a link to Rowan Millers blog EF CTP4 Tips & Tricks: WCF Data Service on DbContext this turned out to be very useful, he talks about getting the underlying ObjectContext see Listing [...]
C# Bits: Using Entity Framework Code First (CTP4) in Dynamic Data
August 14, 2010
EF CTP4 Tips & Tricks: WCF Data Service on DbContext « RoMiller.com…
Thank you for submitting this cool story – Trackback from DigItPort…
DigItPort
October 16, 2010
[...] error message led me to a comment on a post by Rowan Miller on using WCF Data Services against a DbContext, which is exactly what we were doing. Rowan points out that if you're going by experience or [...]
FIX: WCF Data Service with Entity Framework Code-First DbContext doesn’t accept updates - Jon Galloway
January 21, 2011
[...] posts already on how to get DbContext to work with WCF Data Services in .NET 4.0, including this one by Rowan Miller. These posts talk about how to write some extra code to initialize the DataService [...]
Using WCF Data Services with Entity Framework 4.1 and Code First - MSDN Blogs
March 21, 2011
Rowan – thanks for the post, it helped me understand where my “disconnect” was…
Where you say “Obviously this isn’t brilliant and is something that will improve in future releases”… I would refer you to a post by Jon Galloway (http://weblogs.asp.net/jgalloway/archive/2011/01/21/fix-wcf-data-service-with-entity-framework-code-first-dbcontext-doesn-t-accept-updates.aspx?CommentPosted=true#commentmessage) in which he suggests there is a newer CTP5-esque way to accomplish this. However, I’m having no luck with his suggestion.
Any chance you could update your post for the current EF?
Kerry
January 13, 2012
[...] posts already on how to get DbContext to work with WCF Data Services in .NET 4.0, including this one by Rowan Miller. These posts talk about how to write some extra code to initialize the DataService [...]
Using WCF Data Services with Entity Framework 4.1 and Code First - ADO.NET Blog - Site Home - MSDN Blogs
August 20, 2012