6

I'm using LINQPad to connect to the ODATA services on a local CRM organization and I don't know how to perform "joins" or to traverse relationships using LINQPad.

Here is my URL

OrganizationData.svc/New_locationSet?$select=new_state_new_location/new_Region$expand=new_state_new_location

which works just fine in the browser. Here is what I'm doing in LINQPad:

from l in new_locationSet
from s in l.new_state_new_location
select s.new_Region

but I'm getting an error:

An expression of type 'LINQPad.User.New_state' is not allowed in a subsequent from clause in a query expression with source type 'System.Data.Services.Client.DataServiceQuery<LINQPad.User.New_location>'.  Type inference failed in the call to 'SelectMany'.

Any ideas? I've found the LINQPad OData documentation extremely lacking...

Daryl
  • 18,592
  • 9
  • 78
  • 145

1 Answers1

7

You just need to project out what you want to expand, e.g.:

from p in Products
select new {p.Name, CategoryName = p.Category.Name}

or

Products.Select(p => new { p.Name, CategoryName = p.Category.Name})

will yield

http://services.odata.org/(S(readwrite))/OData/OData.svc/Products()?$expand=Category&$select=Name,Category/Name

in LinqPad's Request Log tab.

Mark Stafford - MSFT
  • 4,306
  • 3
  • 17
  • 23
  • So basically since odata has a single data set that it works off of (ie you can't do Odata.svc/Products()Categories()?...) , you have to structure your LINQ query with a single "from" data set and put the joining in the selection as a projection? And since odata already has all of the relationships defined, it will wire it up automatically? – Daryl Jun 29 '12 at 00:52
  • 1
    Yeah - that's pretty much right. In the URL there are no joins (since they're not needed given that there are navigation properties), the client side LINQ to URL translator tries to be very clever about these things and might recognize some joins as navigations, but currently it is very limited (mainly since it doesn't know or have foreign keys). A helpful picture to use is to imagine OData as a graph of objects and the query defines a tree in that graph which you want to return. That is very unlike relational databases where you have tables and the query defines a matrix. – Vitek Karas MSFT Jun 29 '12 at 06:51