I have a parent object with a child collection containing one element, the child collection contains a "grandchild" collection containing 3 elements.
I am loading the parent object from the database using NHibernate as follows
Parent parentObject = session.Query<Parent>()
.FetchMany(x => x.Children)
.ThenFetchMany(x => x.GrandChildren)
.Where(x => x.Id = "someparentid")
.Single();
What I'm finding is that there are duplicate children objects (3 in total) attached to the parent object when there should be only one. (There are 3 grandchild objects correctly attached to each child.) Eager loading the children collection only works correctly.
Do you know how I can achieve loading of the full parent object without duplicate children?
If you map Children and GrandChildren as set, you can avoid the cartesian product. You need to define Children and Grandchildren as collections:
public class Parent
{
...
public virtual ICollection<Child> Children { get; set; }
...
}
public class Child
{
...
public virtual ICollection<GrandChild> GrandChildren { get; set; }
...
}
And in the mapping (using FluentNHibernate):
public class ParentMapping : ClassMap<Parent>
{
public ParentMapping()
{
...
HasMany(x => x.Children)
.KeyColumn("ParentID")
.Inverse
.AsSet()
...
}
}
public class ChildMapping : ClassMap<Child>
{
public ChildMapping()
{
...
HasMany(x => x.GrandChildren)
.KeyColumn("ChildID")
.Inverse
.AsSet()
...
}
}
I was able to use the answer here using QueryOver, it correctly loads the objects while generating efficient SQL (selects per table instead of one huge join).
If you are using Linq, you can simplify it with this:
int parentId = 1;
var p1 = session.Query<Parent>().Where(x => x.ParentId == parentId);
p1
.FetchMany(x => x.Children)
.ToFuture();
sess.Query<Child>()
.Where(x => x.Parent.ParentId == parentId);
.FetchMany(x => x.GrandChildren)
.ToFuture();
Parent p = p1.ToFuture().Single();
Detailed explanation here: http://www.ienablemuch.com/2012/08/solving-nhibernate-thenfetchmany.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With