nhibernatenhibernate-criterianhibernate-projections

How to get nested objects using ICriteria Projections


I have data model like this:

class Hand {
    public int id;
    ...
}
class Person {
    public int id;
    public string name;
    public IList<Hand> hands;
    ...
}

To get data from database, I do this:

ICriteria criteria = databaseSession.CreateCriteria(typeof(Person));

ProjectionList projections = Projections.ProjectionList();

projections
    .Add(Projections.Property("id").As("id"))
    .Add(Projections.Property("name").As("name"))
    .Add(Projections.Property("hands").As("hands"));

projections.Add(Projections.GroupProperty("id"));
projections.Add(Projections.Count("id"), "count");

criteria.SetProjection(projections);

criteria.SetResultTransformer(
    NHibernate.Transform.Transformers.AliasToBean(typeof(PersonDTO)));

But NHibernate does not load nested objects in hands property. It just gives null. Can anyone help me how to get nested objects filled as well (for more than one level depth). Using projections instead of query would be better for me. Note: It would not be issue in the mapping, because when I loaded data without any projection, it worked well.


Solution

  • a possible solution

    var query = databaseSession.CreateCriteria(typeof(Person))
        .JoinAlias("hands", "hand")
        .SetProjection(Projections.ProjectionList()
            .Add(Projections.Property("Id"))
            .Add(Projections.Property("Name"))
            .Add(Projections.Property("hand.Id"))
            .Add(Projections.Property("hand.Foo")))
        .List<object[]>()
        .GroupBy(arr => (int)arr[0])
        .Select(g => new PersonDTO
        {
            Id = g.Key,
            Name = g.First().Name,
            Hands = g.Select(arr => new Hand { Id = arr[2], Foo = arr[3] }).ToList(),
        });
    
    var results = query.ToList();