I am using following Linq query:
from p in People
where p.Name == \"George Lucas\"
select p.TitlesActedIn
where TitlesActedIn is a list. P
Interestingly, the following works:
from p in People
where p.Name == "George Lucas"
select new { p.TitlesActedIn }
as does this:
(from p in People
where p.Name == "George Lucas"
select new { p.TitlesActedIn }).First().TitlesActedIn
The WCF client automatically adds the expansion call in the URI translation:
http://odata.netflix.com/Catalog/People()?$filter=Name eq 'George Lucas'&$top=1&$expand=TitlesActedIn&$select=TitlesActedIn/*
UPDATED: See this question and answer to understand the limitations on Select Many in Data Services + Another solution based on $expand (note this requires the server to support expand)
If this is WCF Data Services and TitlesActedIn is a collection of related movies. Then you can do this in one query only if Person.Name is the primary key.
To illustrate this:
var titles = from p in people
where p.Name == "George Lucas"
from m in p.TitlesActedIn
select m;
Will do what you want but only if Name is the key of the Person entity, otherwise this is unsupported.
If Name is not the key one way to do this (today) is with two queries, something like this:
var key = (from p in people
where p.Name == "George Lucas"
select new {p.Id}).Single().Id;
var titles = from p in people
where p.Id == key
from m in p.TitlesActedIn
select m;
Another option though would be do an expand:
var george = (from p in people.Expand("TitlesActedIn")
where p.Name == "George Lucas"
select p).Single();
var titles = george.TitlesActedIn;
But that relies on the server supporting $expand - which not all servers do...
Note we are currently working on adding any/all support to OData and WCF Data Services, once that is released you would be able to write:
var titles = from t in titles
where t.Actors.Any(a => a.Name == "George Lucas")
select t;
Hope this helps
Note: in the code that gets the key for George Lucas I create an anonymous type because today WCF Data Services doesn't support materializing primitives directly.
A very simple way to do it:
var query = People
.Expand("TitlesActedIn")
.Where(p => p.Name == "George Lucas")
.First()
.TitlesActedIn.Select(t => t.ShortName);
query.Dump();
Its important to note, that this will crash if the name you pass it does not exist. (The First Operator will throw an exception. You would need to either guarantee that the name exists, or do it in two steps.
If you want to do it in one step it comes down to this:(please note what is coming back)
http://odata.netflix.com/catalog/People()?$filter=Name eq 'George Lucas'&$top=1&$expand=TitlesActedIn
You need the expand or it will quit evaluating after the .First()
, because TitlesActedIn will be empty.
It basically translates to select the Person, include (expand) the TitlesActedIn association, then select the name (client side)
The downside of this is that you are pulling back everything (all fields) from the Titles table. So for every title associated to the Person it is returning (Title, Year, Description, ShortName, etc).
If you did this in two queries you could only pull back "ShortName" from the TitlesActedIn association.
I get a similar error if I use a group by clause along with the lambda expression to fetch data using WCF Data Service. I got to know that certain operations are not supported by WCF data services. Please make sure you are not using unsupported LINQ operations.
http://msdn.microsoft.com/en-us/library/ee622463.aspx