WCF Data Services Custom Framework – part 5

Phew it’s been a while but I better get back into it! In the final part of this series I will be going over what we can do client side when we want to query our services. Because of the nature of WCF Data Services to detach our client objects from our server ones this is more of a general discussion about its querying capabilities.

Once you have created the service we can have a look at it straight away. Open up a browser and navigate to your service (For my examples I will use http://localhost:49238/TestService.svc/). You should see a list of all your exposed IQueryable instances. You can get even more information by using the metadata query http://localhost:49238/TestService.svc/$metadata. This shows you all the object properties and relationship. When you create a service reference to your client this is the mechanism that it uses to automatically generate your classes.

Lets get on to the interesting bits now! I’ve created a client program and added my service as a service reference. To be able to use it we have to give it a url like so:

TestEntities entities = new TestEntities(new Uri("http://localhost:49238/TestService.svc"));

All your IQueryable instances are now exposed through this container. However it should be noted that they are now exposed as a DataServiceQuery<> which does have some limitations. Query operations that are not supported out right are things like Group By, Aggregate functions like Sum etc, Any/All, and any kind of Join. It might seem like a lot but the point is to use our business repositories to return well rounded business objects in the first place. This will hopefully reduce the need to use these sort of functions.

I’ll just go over the ones that do work now…

Where

Classic and useful one this!

entities.Contacts.Where(c => c.FirstName.Contains("Felix"));

Queries generated from the container are actually translated to a Uri and when executed actually call the service using the Uri. In this case the generated Uri is http://localhost:49238/TestService.svc/Contacts()?$filter=substringof('Felix',FirstName) – Its cool because you can see this and check out results during debugging.

In this case you can see the Where actually translates to a $filter clause. To see all the sort of things you can filter by (and thus get a feeling for the things you can put in the Where clause) check this link out - http://www.odata.org/developers/protocols/uri-conventions (Section 4.5 for the filter stuff)

Order By

entities.Contacts.OrderBy(c => c.LastName).ThenBy(c => c.FirstName);

http://localhost:49238/TestService.svc/Contacts()?$orderby=LastName,FirstName

Top/Skip

Great for paging…

entities.SiteContacts.Skip(4).Take(5);

http://localhost:49238/TestService.svc/SiteContacts()?$skip=4&$top=5

Expand

Ah ha got you didn’t I! Yes this is not a normal query call and is really an extension of DataServiceQuery<>. When you do any normal query the results you get back don’t include navigation properties – those that link to other objects. Expand tells DS to include these other objects. You can’t go crazy though with this one though as the expand statement only works on the current object.

entities.Students.Expand("Contact,SchoolStudents");

http://localhost:49238/TestService.svc/Students()?$expand=Contact,SchoolStudents

(Note: This can’t be used with Select – if you want extra properties make sure to add them to the projection).

Query Executors (First/Single/Count/ToList)

I’ve grouped these together as they pretty much do what you expect. Just be aware that the moment one of these is called is the moment a query actually is executed across the wire and results are brought back.

Select

I’ve saved the best till last. The capabilities of this method are something special indeed! Have a ponder over this:

(from schoolStudent in entities.SchoolStudents
 select new
 {
     Id = schoolStudent.SchoolStudentId,
     StudentId = schoolStudent.Student.StudentId,
     Contact = schoolStudent.Student.Contact,
     PlacementGroupStudents = schoolStudent.PlacementGroupStudents
 });

http://localhost:49238/TestService.svc/SchoolStudents() ?$expand=Student,Student/Contact,PlacementGroupStudents& $select=SchoolStudentId,Student/StudentId,Student/Contact/*,PlacementGroupStudents/*

Yep, you can pick and choose over WCF Data Services! The only data coming over the wire will be the data specified in the select statement. That is hot stuff! And as if it couldn’t get any better you can actually save these projections back into your model! This is excellent if you want to change a small subset of information from a big object. See http://msdn.microsoft.com/en-us/library/ee473425.aspx for more info.

Well that’s most of it. Going over these queries again really shows to me how much simpler my life can be with this Querying capability over the top of my business layer. It means I can put off writing a series of methods in my service that bring back parts of my database object, or that can account for every parameter my UI layer might throw at it.

Print | posted on Friday, 30 July 2010 5:35 PM

Feedback

No comments posted yet.
Title  
Name
Email (never displayed)
Url
Comments   
Please add 1 and 7 and type the answer here: