How we can fetch more than one grandchild collections

502 views
Skip to first unread message

Ivan Korytin

unread,
Mar 1, 2012, 10:40:35 AM3/1/12
to nhusers
I have this table structure:

ReferralSource - main table
-Phone - join table Rs as one-to-one
- Carrier - child table for Phone
- Type - child table for Phone
I want to get it by Linq query:

Session.Query<ReferralSource>()
.Fetch(x => x.Phone)
.ThenFetch(x => x.Type)
.Fetch(x => x.Phone)
.ThenFetch(x => x.Carrier);
And this query get this SQL code:

select referralso0_.Id,
referralso0_.FirstName,
phonetype4_.TypeName
carrier6_.Name
from REFERRALSOURCES referralso0_
left outer join PHONES phone3_
on referralso0_.PhoneId = phone3_.Id
left outer join PHONETYPES phonetype4_
on phone3_.TypeId = phonetype4_.Id
- duplicated join started
left outer join PHONES phone5_
on referralso0_.PhoneId = phone5_.Id
left outer join CARRIERS carrier6_
on phone5_.CarrierId = carrier6_.Id
- duplicated join finished

How can I remove duplicated left join using fetch?

Itzik Saban

unread,
Mar 1, 2012, 11:33:15 AM3/1/12
to nhu...@googlegroups.com
You can use the Future mechanism:

var future = Session.QueryOver<ReferralSource>()
           .JoinQueryOver<Phone>(x => x.Phone)
           . JoinQueryOver<Type>(x => x.Type)
           .Future();
 Session.QueryOver<ReferralSource>()
           .JoinQueryOver<Phone>(x => x.Phone)
           . JoinQueryOver<Carrier>(x => x.Carrier )
           .Future();

future.ToList();


this way you also avoid a Cartesian Product.


בתאריך 1 במרץ 2012 17:40, מאת Ivan Korytin <ivan.k...@creamtec.com>:

--
You received this message because you are subscribed to the Google Groups "nhusers" group.
To post to this group, send email to nhu...@googlegroups.com.
To unsubscribe from this group, send email to nhusers+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/nhusers?hl=en.



--
Itzik Saban


Ivan Korytin

unread,
Mar 1, 2012, 12:01:59 PM3/1/12
to nhusers
Thank you for your answer, but I have to use Linq-to-Nhibernate.

On Mar 1, 6:33 pm, Itzik Saban <itziksa...@gmail.com> wrote:
> You can use the Future mechanism:
>
> var future = Session.QueryOver<ReferralSource>()
>            .JoinQueryOver<Phone>(x => x.Phone)
>            . JoinQueryOver<Type>(x => x.Type)
>            .Future();
>  Session.QueryOver<ReferralSource>()
>            .JoinQueryOver<Phone>(x => x.Phone)
>            . JoinQueryOver<Carrier>(x => x.Carrier )
>            .Future();
>
> future.ToList();
>
> this way you also avoid a Cartesian Product.
>
> בתאריך 1 במרץ 2012 17:40, מאת Ivan Korytin <ivan.kory...@creamtec.com>:
> my blog <http://itziksaban.blogspot.com/>

CSharper

unread,
Mar 2, 2012, 5:26:40 AM3/2/12
to nhusers
Hi,

I did not try that with the Linq provider but in the case with a one-
to-one association it should be possible to directly add a fetch
specification over multiple navigation paths (until you reach a -to-
many association).

That's why the following might work...
Session.Query<ReferralSource>()
.Fetch(x => x.Phone.Type)
.Fetch(x => x.Phone.Carrier);

Did I get it right that the ReferralSource's Phone property is a one-
to-one? Then at least in HQL that's possible.

Ricardo Peres

unread,
Mar 2, 2012, 6:54:29 AM3/2/12
to nhusers
I think Fetch only supports one level... it has to be:

Session.Query<ReferralSource>()
            .Fetch(x => x.Phone)
.ThenFetch(x => x.Type)
            .Fetch(x => x.Phone)
.ThenFetch(x => x.Carrier);

Ivan Korytin

unread,
Mar 2, 2012, 11:27:46 AM3/2/12
to nhusers
A fetch request must be a simple member access expression of the kind
o => o.Phone; 'x.Phone.Type' is too complex.
So it`s wrong
Reply all
Reply to author
Forward
0 new messages