Yesterday I wrote a quick overview of ADO.NET Data Services. We saw how it exposes a RESTfull API on top of any IQueryable<T> data source. The IQueryable<T> interface is of course at the core of any LINQ enabled data service. It's very easy to write your own custom Data Context if you already have a data source that supports IQueryable<T>. It's worth remembering that anything that provides IEnumerable<T> can be converted to IQueryable<T> by the AsQueryable() extension method, which means we can simply export an in-memory object graph in a RESTfull fashion with ADO.NET Data Services. That's what I'm going to show how to do today.
I got these techniques from an excellent MSDN Magazine article by Elisa Flasko and Mike Flasko, Expose And Consume Data in A Web Services World.
The first thing we need to do is provide a Domain Model to export. Here is an extremely simple example, two classes: Teacher and Course. Note that each entity must have an ID property that the Data Service can recognize as its primary key.
For a read-only service (I'll show insert, update and delete in part 2) you simply need a data context that exports the entities of the domain model as IQueryable<T> properties:
using System.Linq;
using Mike.DataServices.Model;
namespace Mike.DataServices
{
public class SchoolDataContext
{
private static Teacher[] teachers;
private static Course[] courses;
public SchoolDataContext()
{
var johnSmith = new Teacher
{
ID = 1,
Name = "John Smith"
};
var fredJones = new Teacher
{
ID = 2,
Name = "Fred Jones"
};
var programming101 = new Course
{
ID = 1,
Name = "programming 101",
Teacher = johnSmith
};
var howToMakeAnything = new Course
{
ID = 2,
Name = "How to make anything",
Teacher = johnSmith
};
johnSmith.Courses = new[] {programming101, howToMakeAnything};
var yourInnerFish = new Course
{
ID = 3,
Name = "Your inner fish",
Teacher = fredJones
};
fredJones.Courses = new[] {yourInnerFish};
teachers = new[] {johnSmith, fredJones};
courses = new[] {programming101, howToMakeAnything, yourInnerFish};
}
public IQueryable<Teacher> Teachers
{
get { return teachers.AsQueryable(); }
}
public IQueryable<Course> Courses
{
get { return courses.AsQueryable(); }
}
}
}
Note that we're building our object graph in the constructor in this demo. In a realistic implementation you'd probably have your application create its model somewhere else.
Now we simply have to set the type parameter of the DataService to our data context (DataService<SchoolDataContext>):
using System.Data.Services;
namespace Mike.DataServices
{
[System.ServiceModel.ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class SchoolService : DataService<SchoolDataContext>
{
public static void InitializeService(IDataServiceConfiguration config)
{
config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
}
}
}
And we can query our model via our RESTfull API:
And here's all the courses that the first teacher teaches:
Code is here:
No comments:
Post a Comment