views:

470

answers:

3

Does Linq-to-NHibernate support retrieving data from multiple entities in a single query?

e.g.

    Dim query = From f In context.Session.Linq(Of Floor)() _
                Select f.Id, f.Name, f.Building.Id, f.Building.Name

    Dim results = query.ToList()

Where Building is the parent entity of Floor

+1  A: 

It should be possible, as NHibernate supports this natively. Yet I have no experience with Linq-to-NHibernate.

Have you tried the query, and if yes, what was the response?

Jan Jongboom
Exception:{"Index was outside the bounds of the array."}could not instantiate: VB$AnonymousType_0`4[[System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]However, the SQL output is: SELECT id, name FROM floor - so no evidence of a join.
Starfield
+2  A: 

You will need to use the Expand method on session.Linq. For example (sorry, in c#),

var linq = session.Linq<Floor>();
linq.Expand("Building");  //causes "Building" to be eagerly loaded.
//Then your linq query goes here...
Simon
Or, if ICriteria is used - ICriteria.SetFetchMode("Building", FetchMode.Eager);
Arnis L.
Only problem is - this approach is a bit unfriendly with 'repository' pattern.
Arnis L.
Yes, it can be a little difficult with the repository pattern. However, I normally have a repo method that takes a custom interface (like IDomainQuery) that has a IQueryable property that contains the query, and an 'ExpandStrings' property that returns an array of strings that the repository uses to call linq.Expand. Let me know what you think of that?
Simon
+1  A: 

I've been playing with Expand. Interesting point about the Repository pattern too.

The thing that immediately hit me though was the smell of the magic string "Building" in @Simon's example. I did eventually come across this blog post from Marcin Budny.

http://marcinbudny.blogspot.com/2009/10/typed-expand-for-linq-to-nhiberante.html

Works well for me.

Perhentian
Yep, I had that exact thought myself Perhentian! I just left that as an exercise for the reader ;-). I ran into the issue around child collections without an indexer (like ISet), and couldn't think of a quick solution to that. I notice that Marcin created the SubPath stuff for it which is quality. I think I will be using his solution from now on. Thanks for the feedback.
Simon