Re: DistinctRootEntityResultTransformer not available in NHibernate Linq

539 views
Skip to first unread message

CSharper

unread,
Oct 23, 2012, 6:16:05 AM10/23/12
to nhu...@googlegroups.com
I thought that the Fetch and FetchMany-Extensions do exactly what's required: eager load the association and anyway don't deliver duplicates within the query.
 
See also the EagerLoadTests in NHibernate.Test.Linq namespace: the result count in the eager loading cases are the same as in the lazy loading case.
 

Am Dienstag, 23. Oktober 2012 00:11:55 UTC+2 schrieb pete:
I have the same problem as a user describes here: http://groups.google.com/group/nhusers/browse_thread/thread/6a4c233931dc5eea

I just upgraded to NH 3.2.0GA where previously I was using NH2.2.4 with Linq addin. One feature I had in my old repository was SetResultTransformer(new DistinctRootEntityResultTransformer()) to ensure unique records when I eagerly fetched values using left joins. My Repository exposes IQueryable<T>. In NH 3 I am using Session.Query<T>, but how can I add a ResultTransformer to that?

In NH2 with linq provider I could write

        var query = Session.Linq<T>().QueryOptions.RegisterCustomAction(x => x.SetResultTransformer(new DistinctRootEntityResultTransformer()));

That always ensured that the Distinct Results were always applied. This was useful when eagerly fetching a few collections at once (left joins) which produced a Carteasian product.
How could that be done in NH3 with using IQueryable? I know that it could be done with ICriteria but I want to use Linq.

Distinct is not working for this.

Thanks for your help.

CSharper

unread,
Oct 29, 2012, 4:15:39 AM10/29/12
to nhu...@googlegroups.com
It seems that my post on this did not make it to the group (maybe I forgot to press the post button or something like that).
 
I think that Fetch requests must not change the Linq semantics so the result set of a query should be the same no matter what fetch requests are added to that query.
If that's not the case, you should provide a failing unit test in the NHibernate.Test project for your case. There is already a bunch of tests so I would say that the fetch requests work as expected but I cannot say for sure that they *always* work as expected.
 

Am Mittwoch, 24. Oktober 2012 01:02:02 UTC+2 schrieb pete:
Thanks for your reply. That's right, they don't deliver duplicates within the whole resultset. That means the resultset itself is distinct. But when accessing single entities of the query one entity itself is not distinct, because the result is a cartesian product (left outer join) of all entities.
Think of an entity "category" with 10 rows and an entity "subcategory" with 20 rows.
The result of eager fetching both tables will contain 20 rows with all columns of both tables. When accessing entity "category" NHIbernate would return 20 rows instead of 10.

However for simple queries this seems to be working, but not for my case.
I have an entity "list" which can have localized properties which are stored in "listlocales". A list can have one or many "articles". "articles" can also have "articlelocales". An article can only have one list.
My query is

var query = session.Query<Lists>()
                   .FetchMany(x => x.Locales)        // list locales
                   .FetchMany(x => x.Articles)
                     .ThenFetchMany(x => x.Locales); // article locales


When accessing list locales the number of entries is the rowcount of all articles.

Maybe there is a problem that both properties are named "Locales". Otherwise it seems that NHibernate.Linq.ResultTransformer has to be patched ...
Reply all
Reply to author
Forward
0 new messages