WCF Data Services 4.0 in less than 5 minutes

WCF Data Services 4.0 (formerly known as ADO.NET Data Services, formerly known as Astoria) is one of the ways to expose an Entity Data Model from Entity Framework 4.0 in a RESTful / OData way. This article explains how to create such a data service and how to consume it with a browser and with a WPF client.

The Data Service

Start with an empty ASP.NET Application:

Add a WCF Data Service to it:

Also add an Entity Data Model to the ASP.NET project:

Follow the Model Wizard to create a model containing entities on top of the Employee and Person tables from the AdventureWorks2008 database:

In the designer, you should have something like this:

A lot of code was generated, let's add our own 50ct in the service's code behind. First let it inherit from DataService<AdventureWorks2008Entities>:

public class WcfDataService : DataService<AdventureWorks2008Entities>

{ .. }

 

Then modify the InitializeService method as follows. This exposes all operations and grants all access rights (not really a production setting):

public static void InitializeService(DataServiceConfiguration config)

{

    config.SetEntitySetAccessRule("*", EntitySetRights.All);

    config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);

    config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;

}


Believe it or not, we're done (for the first part): the entity model is now exposed in a RESTful way. At the root URL you get an overview of the exposed entities. In the attached sample the root URL is "http://localhost:1544/WcfDataService.svc", but you may of course end up with another port number:

At the "/Employees" address you find all employees:

In your browser this list of employees may appear like this:

This means it's time to -at least temporarily- disable your rss feed reading view. Here's how to do this in IE:

 

 

To reach an individual entity, just type its primary key value in parentheses at the end of the URL, like "http://localhost:1544/WcFDataService.svc/Employees(1)":

You can navigate via the relationships between entities. This is how to reach the Person entity, connected to the first Employee. The URL is "http://localhost:1544/WcfDataService.svc/Employees(1)/Person":

Other OData URI options options can be found here, including:

  • Filtering: http://localhost:1544/WcfDataService.svc/Employees?$filter=JobTitle eq 'Chief Executive Officer'
  • Projection: http://localhost:1544/WcfDataService.svc/Employees?$select=JobTitle,Gender
  • Client side paging: http://localhost:1544/WcfDataService.svc/Employees?$skip=5&$top=2

Version 4.0 also includes support for server side paging. This gives you some control over the resources. Add the following line in the InitializeService method:

config.SetEntitySetPageSize("Employees", 3);


Only 3 employees will be returned now, even if the client requested all:

A Client

Enough XML for now. WCF Data Services also expose a client side model that allows you to use LINQ.

Create a new WPF application:

Add a Service Reference to the WFC Data Service:

Decorate the Window with two buttons and a listbox. It should look more or less like this:

The ListBox will display Employee entities through a data template (OK, that's XML again):

<ListBox

   Name="employeesListBox"

   ItemTemplate="{StaticResource EmployeeTemplate}"

   Margin="4"

   Grid.Row="1"/>


Here's the template. It not only binds to Employee properties, but also to Person attributes:

<DataTemplate

   x:Key="EmployeeTemplate">

    <StackPanel>

        <StackPanel Orientation="Horizontal">

            <TextBlock

               Text="{Binding Path=Person.FirstName}"

               FontWeight="Bold"

               Padding="0 0 2 0"/>

            <TextBlock

               Text="{Binding Path=Person.LastName}"

               FontWeight="Bold"/>

        </StackPanel>

        <StackPanel Orientation="Horizontal">

            <TextBlock

               Text="{Binding Path=JobTitle}"

               Width="180"/>

            <TextBlock

               Text="{Binding Path=VacationHours}"

               Width="60"

               TextAlignment="Right" />

            <TextBlock

               Text=" vacation hours taken." />

        </StackPanel>

    </StackPanel>

</DataTemplate>


The Populate-Button fetches some Employee entities together with their related Person entity, and binds the collection to the ListBox (in version 4.0 two-way bindings are supported for WPF):

private void Populate_Click(object sender, RoutedEventArgs e)

{

    AdventureWorks2008Entities svc =

        new AdventureWorks2008Entities(

            new Uri("http://localhost:1544/WcfDataService.svc"));

 

    this.employeesListBox.ItemsSource =

        svc.Employees.Expand("Person").Where(emp => emp.BusinessEntityID < 100);

}


Here's the result:

The Update-Button updates the number of vacation hours of the company's CEO. It fetches the Employee, updates its VacationHours property, then tells the state manager to update the employee's state, and eventually persists the data:

private void Update_Click(object sender, RoutedEventArgs e)

{

    AdventureWorks2008Entities svc =

        new AdventureWorks2008Entities(

            new Uri("http://localhost:1544/WcfDataService.svc"));

 

    Employee employee =

        svc.Employees.Where(emp => emp.BusinessEntityID == 1).First();

 

    employee.VacationHours++;

 

    svc.UpdateObject(employee);

    svc.SaveChanges();

}


If you now repopulate the listbox, you will see the increased value:

Source Code

Here's the full source code of this sample (just requires VS2010 with no extra downloads): U2UConsult.WcfDataServices.Sample.zip (96,59 kb)

Enjoy!