1. Problem
You have a database that you want to make available via REST and OData programming models.
2. Solution
Take advantage of Visual
Studio 2010 tooling to publish a database via WCF Data Services and the
OData protocol and then access the database from Silverlight 4.
3. How It Works
You already saw the tooling on how to add a Service Reference to an OData service using Visual Studio 2010 in Recipe 1.
In this recipe, you learn how to make a database available as a service
using the tooling in Visual Studio 2010 and then access that service
from Silverlight.
4. The Code
Start by creating an ADO.NET Entity Framework Data Model named Northwind.edmx that contains all of the tables in Northwind in a folder named DataModel in the ASP.NET TestWeb project. Next, create a folder named DataService in the ASP.NET TestWeb project and then add a WCF Data Service item named NorthwindDataService.svc to the DataService folder. Here is the generated data service code:
public class NorthwindDataService :
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.V2;
}
}
You perform the first TODO mentioned in the code by replacing the comment in the constructor with the type TestWeb.DataModel.NorthwindEntities to make the entities available via the Data Service. Next, you edit the InitializeService method to configure access rules for your entities by granting all rights to all entities in this line of code:
config.SetEntitySetAccessRule("*", EntitySetRights.All);
When you run the service to display it in code, it looks like Figure 1.
To view just the Orders data, you can alter the URL by appending Orders to the end like this:
http://localhost:64524/DataService/NorthwindDataService.svc/Orders
Figure 2 shows the results as a feed.
To view the feed as XML, go to
Internet Explorer Tools | Internet Options | Content | Feed and Web
Slice Settings | and uncheck Turn on feed reading view. Figure 3 shows the feed as XML.
Next, select Recipe 2 and right-click to bring up the Add Service Reference menu and click Discover to automatically find the NorthwindDataService in the TestWeb project. Give the service a namespace of NorthwindDataServiceReference and click OK to add the client side code to access the data service.
Add a using clause to MainPage.xaml.cs to bring in the service namespace. The code is similar to that in Recipe 1 and is shown in Listing 2.
Listing 2. The Recipe 9-2 MainPage.Xaml.cs Codebehind File
using System; using System.Linq; using System.Windows; using System.Windows.Controls; using Ch09_LOBApplications.Recipe9_2.NorthwindDataServiceReference; using System.Data.Services.Client;
namespace Ch09_LOBApplications.Recipe9_2 { public partial class MainPage : UserControl { NorthwindEntities NorthwindContext; DataServiceCollection<Customer> Customers;
public MainPage() { InitializeComponent(); } private void UserControl_Loaded(object sender, RoutedEventArgs e) { NorthwindContext = new NorthwindEntities( new Uri("DataService/NorthwindDataService.svc", UriKind.Relative)); Customers = new DataServiceCollection<Customer>(NorthwindContext); Customers.LoadCompleted += new EventHandler<LoadCompletedEventArgs>(Customers_LoadCompleted); }
void Customers_LoadCompleted(object sender, LoadCompletedEventArgs e) { if (e.Error == null) { // Load all pages of Orders before binding. if (Customers.Continuation != null) { Customers.LoadNextPartialSetAsync(); } else { // Bind the root StackPanel element to the collection; // related object binding paths are defined in the XAML. NorthwindDataGrid.ItemsSource = Customers; NorthwindDataGrid.UpdateLayout();
// Re-enable the button since the loading is complete. GetCustomersBtn.IsEnabled = true;
// Set the focus to the first order, which loads the related items. NorthwindDataGrid.SelectedIndex = 0; } } else { MessageBox.Show( string.Format("An error has occured: {0}", e.Error.Message)); GetCustomersBtn.IsEnabled = true; } }
private void GetCustomersBtn_Click(object sender, RoutedEventArgs e) { NorthwindDataGrid.DataContext = null;
var CustomersQuery = from customers in NorthwindContext.Customers select customers;
Customers.LoadAsync(CustomersQuery); } } }
|
Figure 4 shows the data displayed in the final user interface.