17 Oct
2010

OData’s DataServiceQuery and removing the .Expand(“MagicStrings”) –Part II

Category:General PostTag: :

In a previous post I elaborated on the problem of magic strings in OData service queries, and gave a quick (but lacking in depth) statically typed helper solution.

A commenter mynkow left a note stating that my solution would not work with nested objects. I initially replied asking if he could give an example (as I hadn?t run into that scenario yet being a noob to OData). He didn?t get back to me, but it wasn?t long before I ran into the problem he was talking about.

If we go back to LinqPad and look again at the Netflix OData api. Let?s say we want to pull down the People, their related TitlesDirected and the TitlesDirected ScreenFormats. (No real world scenario there ? just made it up because they?re related properties). The OData query (with magic strings) would look like:

(from x in People.Expand("TitlesDirected/ScreenFormats")
select x).Take(5)

If you tried to take the above and translate it to my ?no magic string? fix from the previous post you would get something like.

(from x in People.Expand(p => p.TitlesDirected /* Now what? dead end. /ScreenFormats*/ )
select x).Take(5)

Now that the problem in my solution was apparent, and using his example as a quick guide (It wasn?t quite what I was looking for, but had the general theme). The solution became more than a few lines of code and I wanted to wrap some tests around the whole thing just to verify it was all working correctly?

ODataMuscle was born:

http://github.com/Staxmanade/ODataMuscle

Sorry for the name. Just think of ?Strong Typing? your OData queries and giving them a little Muscle. I threw this little project up on github since this blog is not the best place to version code and if anyone felt inclined to extend it they could easily fork it and do so.

I hacked the initial version together, and once a co-worker of mine was done with it I think he cleaned it up nicely.

This new version now supports expanding not only child properties, but grandchild properties and grandchild properties of collections. (That doesn?t seem to translate well?)

EX: our little Netflix example from above would now look like

(from x in People.Expand(p => p.TitlesDirected.Expand(p2 => p2.ScreenFormats))
select x).Take(5)

Which would translate into the following query

http://odata.netflix.com/catalog/People()?$top=5&$expand=TitlesDirected/ScreenFormats

Thanks to mynkow for the initial feedback and I hope this helps someone else?

7 thoughts on “OData’s DataServiceQuery and removing the .Expand(“MagicStrings”) –Part II

  1. Thanks Stuart.

    I’ve included those helpers as well.

    I also recently added a little wrapper for use on the server side when accessing the DataServiceConfiguration.

    Appreciate the feedback.

  2. This is failing to me running LINQPad 4. the compiler error is: “Cannot convert lambda expression to type ‘string’ because it is not a delegate type”. Besides, the second Expand invocation applies to TitlesDirected which is not a DataServiceCollection type but a Collection one. Any idea of what I am doing wrong.

    Thanks for the nice code, Jason.

  3. Thanks, Jason. The prototype with the IEnumerable argument will cater for a broader range of scenaries.

  4. This looks really cool.  But I can’t get it to work.  I admit to not being an expert with LinqPad’s configurations.  I added a Plugins folder and compiled your code and put ODataMuscle.dll in there.  But when I open up LinqPad, your examples don’t work…

    What am I missing?

  5. Hey Stephen.

    After you’ve downloaded and compiled the code.

    If you right click on the LinqPad query and select “Query Properties”. You first have to use the “Additional References” tab to select the ODataMuscle assembly. Then go to the “Additional Namespace Imports” and put in “ODataMuscle”.

    This should work for you. By the steps above I was able to execute the following query against the Netflix OData api.

    (from g in People.Expand(g=>g.TitlesActedIn)select g).First()

    Hope this helps.

Comments are closed.