I wrote two posts about WCF Data Services sometimes back. First post was as Introduction to
WCF Data Services and OData and the second one was
WCF Data Services with Silverlight. This post will be a add-on to both these previous posts.
WCF Data Services supports multiple provider models for exposing data as an Open Data Protocol (OData) feed which are as follows. I am highlighting the main three of them.
- Entity Framework Provider
- Reflection Provider
- Custom Provider
- Streaming Provider
- Action Provider
Today let’s see how we can implement a WCF Data Service with
Entity Framework Provider. If you have read my previous post on
WCF Data Services with Silverlight, you might notice that I have used Entity Framework Provider there. But today let's cover up a more detailed post on WCF Data Services with Entity Framework Provider.
I have created a empty a ASP.NET web application. Now let’s start by adding a ADO.NET Entity Data Model to the project.
|
ADO.NET Entity Data Model |
Now I am asked to create a model with existing database or to create a empty model. I am going with the Empty model, so we can learn all these from the scratch.
|
Empty Model |
I am clicking finish and I am getting a empty model designer. Now let’s create some entities and add some associations.
I am right clicking on the designer and selecting Add New –> Entity called "Employee". I am creating a Key property which is “EmployeeId” and type I am leaving it as it is which is Int32.
|
Add Entity |
|
Entity Added |
Now I am right clicking on the Employee entity and adding some Scalar Properties which are “FirstName” and “LastName”. From the properties window of these Scalar Properties we can change the things like data type etc.
Same way I am creating two other entities which are “Department” and “JobRole”. Finally I am getting the following.
|
Entity Relationship Diagram without Associations |
Now let’s create some associations. I am right clicking on the designer and selecting Add New->Association. I am creating a relationship between Employee and Department which is Employee can only belong to one Department and one Department can have many Employees.
|
Add Association |
Same way I am creating a relationship between Employee and JobRole in which Employee can have many JobRoles and one JobRole can have many Employees.
|
Add Association |
Once this is done I am getting the following model.
|
Entity Relationship Diagram with Associations |
Now let’s right click on the designer and select “Generate Database from Model” to create a database from this model.
I have already created a blank database called “EFProviderDB” and let’s create a connection to this particular database.
|
Choose Data Source |
|
Connection Properties |
|
Generate Database Wizard |
|
Generate Database Wizard |
OK, Now what I have to do is run this query on the SQL Server Management Studio to create my tables and the relationships. After running the query I can see my tables got created and their relationships.
Now let’s add some data to expose via WCF Data Services.
|
Tables created in the database |
Once the data is added to the tables, I am going to add new project item which is “WCF Data Service”.
|
WCF Data Service |
The Visual Studio will create a service which is of WCF Data Service template.
public class WcfDataService1 : DataService< /* TODO: put your data source class name here */ >
{
// This method is called only once to initialize service-wide policies.
public static void InitializeService(DataServiceConfiguration config)
{
// TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.
// Examples:
// config.SetEntitySetAccessRule("MyEntityset", EntitySetRights.AllRead);
// config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All);
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
}
}
In simple this is a service class which is derived from
DataService of type T. It has a single static method which is InitializeService(…). What this class does is it will expose data in a particular context which is T.
Now I am going to modify this class. First I need to find out what the context is. For that I am opening the Model1.Context.cs and I am copying the the class name, in here it’s “Model1Container”. Now this is my data service type.
|
Exposing Context |
Now I am modifying the InitializeService(…) method as follows. I am setting up a entity access rule for all the entities, so consumers can read all data.
public class WcfDataService1 : DataService<Model1Container>
{
// This method is called only once to initialize service-wide policies.
public static void InitializeService(DataServiceConfiguration config)
{
// TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.
// Examples:
config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
// config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All);
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
}
}
I can even modify the method in the following way, so only two entities are exposed (“Employee” and “Department”) to outside.
public static void InitializeService(DataServiceConfiguration config)
{
// TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.
// Examples:
config.SetEntitySetAccessRule("Employee", EntitySetRights.AllRead);
config.SetEntitySetAccessRule("Department", EntitySetRights.AllRead);
// config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All);
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
}
You can set various rights here and it’s up to you to explore. For this demo I am exposing all the entities.
And that’s it.When I run the project I can see my WCF Data Service up and running.
|
Up and Running WCF Data Service |
Now let’s see how we can consume this data service. I am creating a console application and adding a service reference to my created WCF Data Service.
Now I am writing the following code.
using ConsoleApplication1.svcWcfDataService;
using System;
using System.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Model1Container modelContext = new Model1Container(new Uri("http://localhost:51639/WcfDataService1.svc/"));
var employees = from e in modelContext.Employees
select e;
foreach (var e in employees)
{
Console.WriteLine("{0}, {1}", e.LastName, e.FirstName);
}
Console.ReadLine();
}
}
}
I am creating a object of my data context and then I have wrote a LINQ query to retrieve the data. Behind the scene what's happening is, the LINQ query get transformed into REST-like URI syntax and executes HTTP methods such as “GET”,“POST” etc based on my request.
I am attaching a sample project to my SkyDrive, so you can play around.
Appreciate your feedback.
Happy Coding.
Regards,
Jaliya