[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

4 thoughts on “[OData] Use OData data with WCF Data Services and Silverlight 4”

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

  2. 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.

  3. @tony : if I have a label instead of my grid, in the cbCustomers_SelectionChanged method, I add this code :
    lblContact.Content = _selectedCustomer.ContactName;

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>