views:

620

answers:

1

I've got a problem with NHibernate trying to load a small hierarchy of data. My domain model looks like:

class GrandParent
{
    int ID{get;set;}
    IList<Parent> Parents {get; set;}
}

class Parent
{
    IList<Child> Children {get; set;}
}

class Child
{
}

and I would like to eager load all parents and children for a given GrandParent. This Linq-to-NH query creates the correct SQL and loads the GrandParent as expected: (the example assumes the grandparent has 2 parents who each have 2 child objects - so 4 child objects in total).

var linq = session.Linq<GrandParent>();
linq.Expand("Parents");
linq.Expand("Parents.Children");
linq.QueryOptions.RegisterCustomAction(c => 
    c.SetResultTransformer(new DistinctRootEntityResultTransformer()));
var grandparent = (select g from session.Linq<GrandParent>()
                   where g.ID == 1
                   select g).ToList();

Assert(grandparent.Count == 1); //Works
Assert(grandparent.Parents.Count == 2); //Fails - count = 4!

The grandparent.Parents collection contains 4 items, 2 of which are duplicates. It seems the DistinctRootEntityResultTransformer only works on collections 1 level deep, so the Parents collection is duplicated depending on how many Child objects each parent has.

Is it possible to get NH to only include the distinct Parent objects?

Thanks very much.

+1  A: 

If your mapping is set to FetchType.Join, try changing it to FetchType.Select.

mxmissile
Thanks mxmissile, then will work, although you can't specify fetch type in Linq-to-NH (unless I'm missing something), and it's not something I want to use all the time so I'm reluctant to modify the mappings.Another fix is to change the IList<> collections to ICollection<> and use 'set' instead of 'bag' in the mapping. I've also hacked a ResultTransformer together to deal with this, and will provide a link here once I've got it to a reasonable standard.
Simon
@Simon, you can specify default fetch type in the mappings
zvolkov