When I first realized that the WebDataQuery<T> class implemented the IQueryable<T> interface, two things became very apparent to me: this baby was going to be LINQable (that’s a sweet word), and I could now die a happy, yet pathetically nerdy man. Now, you may be wondering how I came to the conclusion that LINQ could be used in conjuction with a data service query, and to explain that let me go off on a brief tangent…
Brief LINQ Tangent
LINQ’s foundation is essentially composed of a collection of extension methods called the Standard Query Operators. Those methods represent all possible functions that can be performed on a data source, and are global to all flavors of LINQ (some LINQ flavors define their own operators, but they are not considered standard). Those extension methods are defined for two types: IEnumerable<T>, and IQueryable<T>, within the Enumerable and Queryable classes respectively. What that means is that any class that implements either of those two interfaces, would automatically “inherit” the list of standard query operators, allowing LINQ statements to be written against it. All that would be left is for the flavor specific logic to be implemented that would enable the LINQ query to actually work.
Keep in mind, that is a pretty watered down explanation of how LINQ works, but hopefully it provides enough primer to merit my above reasoning. Now that we understand that ADO.NET Data Services has “tapped” into the LINQ world by making it’s query object (WebDataQuery<T>) implement IQueryable<T> (with the corresponding implementation logic), we can begin to leverage that beautiful truth for our own benefit.
There are two questions you may be asking yourself right now:
- “What is so special about ADO.NET Data Services being queryable with LINQ?”
- “If LINQ support is so important, why the hell did you wait till part 5 to introduce it?!”
If you have already embraced LINQ, then question #1 would be pretty much laughable. I don’t want to get into a description of LINQ or its benefits too much here, but I will say a few things:
- One syntax to rule them all! When you learn LINQ, and become familiar with the standard query operators, you can seamlessly work with any data source that supports it, with extreme ease.
- You don’t have to be too concerned with the underlying implementation of each LINQ flavor to work with its respective data source. LINQ is a wonderful facade that makes all data sources look the same (to a degree).
- Most importantly, LINQ allows you to query data intuitively. When you get comfortable with the LINQ syntax/operators you become very capable of writing sophisticated queries that might be otherwise tricky using the native query approach of the underlying data source.
What do those three points mean for using LINQ with ADO.NET Data Services? It means that any preexisting knowledge of LINQ becomes completely transferable to the context of a data service. All the time you’ve spent on mastering LINQ was not in vain, and in fact, was a great mental investment on your part. You may have noticed that while the URL parameters and RESTful interface of the data service is pretty straightforward, it’s not exactly the most intuitive coding style, it’s yet another API to learn, and as the queries get more advanced, the uglier the URL’s become. Sounds like the perfect candidate for LINQ to me…
So getting back to question #2 above. I waited this long to cover LINQ To Data Services for one reason: because while LINQ provides a powerful abstraction of the underlying query logic, it shouldn’t be a replacement for understanding how the underlying data is actually manipulated. LINQ should be a tool used by developers who know how to work with the data natively, but would prefer not to. Does that mean you should go out and ensure you understand every single detail of how each LINQ flavor works? Absolutely not, that would take forever, and probably wouldn’t have much value for you. But, since ADO.NET Data Services is brand new, we can all take the time to learn it from the ground up, and have it mastered long before it’s officially released. Plus, how could you fully appreciate just how awesome LINQ To Data Services is without knowing what life was like without it?
“Alright Jonathan, enough of this high-level theory jabber. I already know all of this. Get to some actual code for god’s sake!!!” Let’s take a look at some code we’ve created in previous posts, and see how the same logic could be accomplished, but using LINQ.
To retreive all carriers, ordered by name, we were previously doing:
Which could be converted into:
Or:
Depending on which syntax you prefer. All three examples achieve the exact same result, but each express a different level of clarity. Example two is arguably the most intuitive, while example three is a little more compact. The question of which form to use it up to you. LINQ should be viewed as an alternative, not a doctrine.
“Big deal!”, you might say, “that example is so trivial, neither method really stands out as being that much better than the other.” That may be true, so let’s see some an example that sets using LINQ apart from querying the data service using a URL. Here is a somewhat involved LINQ query:
Would you agree that it’s pretty clear what I’m trying to achieve with that query? I’d say so. The code is explicit, and it’s easy to read. What would that same query look like without LINQ?:
That isn’t the worst code in the world, but in comparison to the LINQ statement, it sure looses a lot of it’s appeal. Aside from being more explicit, the LINQ query is also strongly typed, and has full intellisense. If you were typing a long URL in a call to CreateQuery, the more complex the query gets, the more likely it becomes that you’ll make a typo. We all know there is nothing more beautiful than hand-typing an obnoxiously long string, just to get a run-time error mocking us of a misspelled word. That’s why the DataTable’s Compute and Select methods were so successful (by successful I mean completely deprecated in favor of the extremely superior LINQ To DataSet).
As much as I love LINQ I could pretty much go on all day showing examples of queries that would make you cry out with joy. As this article wasn’t meant to teach LINQ, there isn’t really much more to say (that’s a first for me right?) that is specific to ADO.NET Data Services. There is no rocket-science behind using LINQ To Data Services. Like I mentioned before, if you already know LINQ, then that is all you need to hit the ground running here. If fact, someone with knowledge of LINQ, and virtually no knowledge of ADO.NET Data Services could easily begin writing queries.
The important aspect to take away from this article is to deepen your appreciation for both LINQ and ADO.NET Data Services. When LINQ was first introduced, it was pigeon-holed by many as a way to write SQL in code. Obviously that stereotype has since been done away with, but how much deeper does it’s value grow now that we see it fully implemented as an abstraction over building URLs? ADO.NET Data Services was initially seen as a way to query your database over the web. Throughout this article series we’ve shattered that ridiculous rumor, and seen just how powerful and extremely flexible data services are. And with data services having full LINQ support, what better argument could there be that they fit nicely into the .NET ecosystem? When two new technologies have an integration story like this, everybody wins.
So now that we’ve covered the entire gamut of consuming a data service from within a client application, we need to focus our attention on another client environment, namely JavaScript. ADO.NET Data Services has a full-featured JavaScript API that works beautifully with the ASP.NET AJAX libraries, enabling you to do some pretty sweet stuff. In the next article, we’ll cover just how exactly to achieve said sweetness.
0 Responses to “ADO.NET Data Services Part 5: LINQ”
Leave a Reply