ADO.NET Data Services: CLR-based data models and navigation links

As you are probably aware, one of the new additions to the .NET Framework 3.5 SP1 is a technology called ADO.NET Data Services (code name Astoria). ADO.NET Data Services natively supports ADO.NET Entity Framework (EF) models. However Data Services it is not limited to EF.

ADO.NET Data Services can deploy consistent representations of data regardless of the underlying data source. This approach has made CLR-based data models first class citizens. See here for a comprehensive guide on using CRL-based data models.

Imagine the following class diagram that represents two entities:

 

As you can see, Library has a collection of Books. Therefore Library.Books can be considered a one-to-many resource navigation link to a collection of Books.

public class Library

{

  public int LibraryID { get; set; }

  public string LibraryName { get; set; }

  public List<Book> Books { get; set; }

}

public class Book

{

  public int BookID { get; set; }

  public string BookTitle { get; set; }

}

A simple Data Services’ resource container exposing a list of libraries may look similar to the following:

public class LibraryDataModel

{

  static List<Library> s_libraries = ...;

  public IQueryable<Library> Libraries

  {

    get

    {

      return s_libraries.AsQueryable();

    }

  }

}

Unfortunatly exploring this data model – by perhaps browsing to the URI that exposes this model – may fail throwing an exception similar to the following:

Request Error: The server encountered an error processing the request. The exception message is 'The property 'Books' on type 'AstoriaWeb.Library' is not a valid property. Properties whose types are collection of primitives or complex types are not supported.'

This means that ADO.NET Data Services was not able to automatically consider Books as a resource set that can be referenced using resource navigation links from Library resources. In fact, without some more information, it is really hard for Data Services to automatically expose a new resource set through a resource container.

So how can you avoid this? For this release of Data Services at least, you need to explicitly expose Books as a resource set in the resource container:

public class LibraryDataModel

{

  static List<Library> s_libraries = ...;

  static List<Book> s_books = ...;

  public IQueryable<Library> Libraries

  {

    get

    {

      return s_libraries.AsQueryable();

    }

  }

  public IQueryable<Book> Books

  {

    get

    {

      return s_books.AsQueryable();

    }

  }

}

This article was written based on .NET Framework 3.5 SP1 Beta.