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