[OData] Use OData data with WCF Data Services and Silverlight 4

As seen before, OData (Open Data Protocol) is a protocol on top of HTTP, with a REST architecture and provide XML formatted data (e.g.: ATOM). WCF Data Services, included in Silverlight 4,will help us to handle data with OData.

The purpose is to build a Silverlight master-detail application composed of a ComboBox control to choose a customer and a DataGrid Control to see all the Customer orders. We will use Customers and Orders tables from Northwind OData feed which is at this address : http://services.odata.org/Northwind/Northwind.svc/

Add Service Reference

We create a Silverlight 4 application and we add, in the Silverlight project, a reference to the service which have the Northwind database OData feed. We will use WCF Data Services. Right-click on the Silverlight project, and a click on "Add Service Reference", a dialog box appears and the address of the OData feed must be written in the textbox "Address". And finally, click on the "Go" button to verify the data exposed by the service.

Add Service Reference

After clicking the "Ok" button, you will find, in the hidden files of your solution, that WCF Data Services added 3 new files :

  • Reference datasvcmap : it's a configuration file which contains all information about your service.
  • Reference.cs : it's an Entity Data Model file which contains all data information about your database.

Add Service Reference

Then an XAML interface is built to display data with a ComboBox control and a DataGrid control :

<UserControl.Resources>
  <DataTemplate x:Key="DataTemplateComboBoxItelCustomers">
    <TextBlock Text="{Binding ContactName}"/>
  </DataTemplate>
</UserControl.Resources>

<Grid x:Name="LayoutRoot" Background="White">
  <Grid.RowDefinitions>
    <RowDefinition Height="40"/>
    <RowDefinition Height="*"/>
  </Grid.RowDefinitions>
  <ComboBox Grid.Row="0" ItemTemplate="{StaticResource DataTemplateComboBoxItelCustomers}" Name="cbCustomers"     
  
SelectionChanged="cbCustomers_SelectionChanged" />
  <sdk:DataGrid AutoGenerateColumns="True" Grid.Row="1" Name="dgOrders" />
</Grid>

From the code-behind point of view, the following members have to be declared to use the data from your service :

private DataServiceCollection<Customer> _customers;
private DataServiceCollection<Order> _orders;
private Customer _selectedCustomer;
private NorthwindEntities _context;

Then, in the Loaded event of your User Control, the context must be initialized with your service and the objects must be initialized to cache Customers and Orders data, through DataServiceCollections of WCF Data Services. A Linq request will select all the Customers and sort them by ContactName. Finally, the LoadSync method is called to collect the data from the Linq request:

_context =new NorthwindEntities(new Uri("http://services.odata.org/Northwind/Northwind.svc/"));

_customers
=new DataServiceCollection<Customer>();
_customers.LoadCompleted +=
new EventHandler<LoadCompletedEventArgs>(_customers_LoadCompleted);

_orders
=new DataServiceCollection<Order>();
_orders.LoadCompleted +=
new EventHandler<LoadCompletedEventArgs>(_orders_LoadCompleted);

var query
= from g in _context.Customers
            orderby g.ContactName
            select g;
_customers.LoadAsync(query);

 

When the LoadAsync is called, the LoadCompleted event will be raised when the data loading is finished. You then just need to bind the data to your controls :

void _customers_LoadCompleted(object sender, LoadCompletedEventArgs e)
{
 
if (_customers.Continuation !=null)
  {
     _customers.LoadNextPartialSetAsync();
  }
 
else
  {
     cbCustomers.ItemsSource
= _customers;
     cbCustomers.UpdateLayout();
     cbCustomers.SelectedIndex
= 0;
  }
}

void _orders_LoadCompleted(object sender, LoadCompletedEventArgs e)
{
 
if (_orders.Continuation !=null)
  {
     _orders.LoadNextPartialSetAsync();
  }
 
else
  {
     dgOrders.ItemsSource
= _orders;
     dgOrders.UpdateLayout();
  }
}

Then in the SelectionChanged Customers' ComboBox, when the user chooses a Customer, the CustomerID is used to select the corresponding orders in the Linq request. The LoadAsync method allows to load the data:

_orders.Clear();
_selectedCustomer
= cbCustomers.SelectedItem as Customer;

if (_selectedCustomer !=null)
{
   var query
= from g in _context.Orders
               where g.CustomerID == _selectedCustomer.CustomerID
               select g;
   _orders.LoadAsync(query);
}

 

Finally, there we are :

Add Service Reference

Published Thu, Jun 10 2010 15:40 by Audrey PETIT

Comments

# re: [OData] Use OData data with WCF Data Services and Silverlight 4

This is a great demo.  One problem I had was in copy-pasting from the site the XAML is sort of messed up.

Thursday, June 24, 2010 9:03 AM by darren

# re: [OData] Use OData data with WCF Data Services and Silverlight 4

Some spaces had been forgotten in the XAML, I just add them. If your problem persists, thank you for sending me your error message.

Thursday, June 24, 2010 9:12 AM by Audrey PETIT

# re: [OData] Use OData data with WCF Data Services and Silverlight 4

thanks for the demo.  let's say i have a textbox or a label instead of a grid or combobox.  how do i bind data to it, say, the customer's name?  thanks.

Thursday, June 24, 2010 12:20 PM by tony

# re: [OData] Use OData data with WCF Data Services and Silverlight 4

@tony : if I have a label instead of my grid, in the cbCustomers_SelectionChanged method, I add this code :

lblContact.Content = _selectedCustomer.ContactName;

Thursday, June 24, 2010 3:22 PM by Audrey PETIT

Leave a Comment

(required) 
(required) 
(optional)
(required) 
If you can't read this number refresh your screen
Enter the numbers above: