Cover

Using ADO.NET Data Services in Silverlight 2 Beta 2

Url: http://msdn.microsoft.com/en-us/data/bb931106.aspx
ADO.NET Data Services
UPDATE: I had the PUT/POST reversed.  It reads correctly now.  (Thanks to commenter Rob for pointing it out).

Now that Silverlight 2 Beta 2 has launched, we have the ability to consume ADO.NET Data Services (formerly Astoria) from within Silverlight projects. ADO.NET Data Services are a perfect match for client-side technologies like Silverlight and ASP.NET AJAX.

For the uninitiated, ADO.NET Data Services is a new part of the .NET 3.5 framework that supports exposing a data model (e.g. LINQ for SQL, Entity Framework, etc.) as a set of queryable REST endpoints. ADO.NET Data Services maps the four data verbs into the four HTTP verbs:

  • Create == POST
  • Read == GET
  • Update == PUT
  • Delete == DELETE

Essentially it provides a way to use a data model across the firewall. It works by exposing IQueryable endpoints through a URI-based syntax allowing developers control over how the data is retrieved through:

  • Filtering
  • Sorting
  • Paging
  • Shaping

In addition ADO.NET Data Services utilizes JSON and Atom (though Plain Old XML may be supported eventually) as the serialization formats. These make it easy to consume in client-side interfaces like Silverlight and AJAX. For more information on ADO.NET Data Services, see there site:

http://msdn.microsoft.com/en-us/data/bb931106.aspx

Before you can consume a Data Service in Silverlight, you will need to create a model and service.  See Guy Burstein’s walkthrough of creating the service here:

http://blogs.microsoft.co.il/blogs/bursteg/archive/2008/05/12/visual-studio-2008-sp1-ado-net-data-service-walkthrough.aspx

You *can* use LINQ to SQL as your data model but currently it does not have support for updating via ADO.NET Data Services so if you need to read and write data, you should start with an Entity Framework data model.

In Silverlight 2 Beta 2, ADO.NET Data Services is composed of an in-memory library allows asynchronous LINQ queries that are translated into the URI syntax automatically. Before you can get started you will need a a client-side version of the Data Context object and data contract classes for the entities in your data model. To do this, simply use the DataSvcUtil.exe tool located in the *C:\Windows\Microsoft.NET\Framework\v3.5* directory. Typically you would call it by specifying the URI of the service, the name of the class file to create and what language to use:

DataSvcUtil.exe /uri:http://localhost:8888/YourService.svc 
                /out:dataclass.cs 
                /language:CSharp

```csharp

Once that class is created, add it to your Silverlight project.  You will also need to add a reference to the **System.Data.Client.Services.dll** assembly. Now we are ready to get some data.

First we need to create an instance of the context class.  This class exposes each of the model types as queryable properties.  When creating an instance of the class, you must specify a URI to the service itself:


```csharp
NorthwindEntities ctx = 
  new NorthwindEntities(new Uri("/Products.svc", UriKind.Relative));

```csharp

Querying data with Data Services looks much like any other LINQ-based query:


```csharp
var qry = from p in ctx.Products
          orderby p.ProductName
          select p;

Normally, you could execute the query directly by calling something like ToList() against the query.  Since that operation would cause a synchronous web request to happen across the network, that isn’t supported in Silverlight 2 Beta 2.  In fact, if you try you will simply get a NotImplemented exception. In order to execute these queries, you will need to cast the query into a DataServiceQuery.  The DataServiceQuery allows you to call BeginExecute to start an asynchronous query as seen below:

// Cast the query to a DataServiceQuery
DataServiceQuery<Product> productQuery = 
                                  (DataServiceQuery<Product>)qry;

// Start the execution
productQuery.BeginExecute(new AsyncCallback(OnLoadComplete), 
                          productQuery);

```csharp

Once the query completes, it will call the **OnLoadComplete** method that was specified in the **AsyncCallback**.  In this method, you first grab the **DataServiceQuery** that you sent with the request then end the execution to retrieve the results as seen below:


```csharp
void OnLoadComplete(IAsyncResult result)
{
  // Get a reference to the Query
  DataServiceQuery<Product> productQuery = 
    (DataServiceQuery<Product>)result.AsyncState;

  // Get ther esults and add them to the collection
  List<Product> products = productQuery.EndExecute(result).ToList();
}

```csharp

While its not as straightforward as synchronous execution, the new ADO.NET Data Services certainly works well in Silverlight 2 Beta 2 and provides a great way to use existing or planned data models over Internet applications. There are a couple of caveats:

- Error handling and communication is very confusing right now as most real errors are being swallowed by the server instead of communicating back to the client. To find out what is really happening, use of [Fiddler](http://www.fiddlertool.com/fiddler/) and enabling breaking on the throwing of all .NET exceptions will help a lot.
- There are bugs on updating data that may get in your way.  Using Batch Saves will solve most of these issues.
- Currently the Data Contract objects do not support **INotifyPropertyChanged** or **INotifyCollectionChanged** so data binding may be affected in some cases.There are partial methods for detecting changes to specific properties which makes implementing the **INotifyPropertyChanged** interface trivial, but not quick. Future versions (e.g. post-RTM) will give us better control over the generation of the data contract classes.
- There is no built-in Visual Studio support to build the data contract/context classes.  This is also coming soon, though the exact schedule is unknown.


I am currently working on two examples for this (a simple one and a more complex one) as well as an article for MSDN, all of which will greatly expand the details of how to use ADO.NET Data Services (including how to save changes back to the server. Be sure to watch here for details of those samples and articles.