views:

280

answers:

2

Is there a way to use a LINQ expression to request a Count query from the Netflix oData service in Silverlight 4?

The Netflix documentation shows that you can return counts by appending $count to a request for a collection, but a URL like this:

http://netflix.cloudapp.net/Catalog/Genres/$count

Is not generated from an expression like this:

var count = (from g in catalog.Genres select g).Count();

The above code returns an error saying that the Count method is not supported. Is there a way to do this in LINQ, or do I just need to make WebClient request to get the value?

+1  A: 

It works in LinqPad 4 using C# 4.0

var count = (from g in Genres select g).Count();
count.Dump();

Result: 518

In LinqPad 2 using C# 3.0 the error appears.

Nicholas Murray
I updated the original post, but I forgot to mention that I am doing this in Silverlight 4. It appears this approach, going against a DataServiceCollection is not supported in Silverlight.
Craig Shoemaker
Thanks! - about the podcast :)
Craig Shoemaker
+3  A: 

Count and LongCount are not supported in Silverligth because they require a synchornous execution of the query. Since Silverlight requires all network operations to by asynchronous this is not possible.

You can either issue the HTTP query in question programatically not using DataServiceContext (or related classes), since the $count returns a text representation of the number, parsing the response is not that hard.

Or you can use a bit of a trick. You can use IncludeTotalCount() to add $inlinecount=allpages query option to the query which will include the count in the response. Then to not download all the entities from server, you can use Take(0) which will add $top=0 and thus return empty result set. But the inline count will still contain the right number.

You can access the inline count on the QueryOperationResponse.TotalCount property. Something like this:

    NetflixCatalog ctx = new NetflixCatalog(new Uri("http://netflix.cloudapp.net/Catalog"));
var q = (DataServiceQuery<Genre>)ctx.Genres.IncludeTotalCount().Take(0);
q.BeginExecute((ar) =>
    { 
        QueryOperationResponse<Genre> r = (QueryOperationResponse<Genre>)q.EndExecute(ar);
        r.TotalCount.ToString(); // Use the count in whatever way you need
    }, null);
Vitek Karas MSFT