Search code examples
c#.netnhibernateormqueryover

Getting properties from a child


I have the following entities:

public class Parent
{
     int Id { get; set; }
     string ParentName { get; set; }
     List<Child> Children { get; set; }
}

public class Child
{
     int Id { get; set; }
     string ChildName { get; set; }
}

and the following dto:

public class ParentDTO
{
     int Id { get; set; }
     List<string> ChildrenNames { get; set; }
}

using QueryOver code below I can get the Parent values

 ParentDTO result = null;
 Parent parentAlias = null;
 Child childAlias = null;

 var query = session.QueryOver(() => parentAlias)              
            .JoinAlias(() => parentAlias.Children, () => childAlias, JoinType.LeftOuterJoin)                           
            .SelectList(list => list.Select(c => c.Id).WithAlias(() => result.Id)
                                    .Select(c => c.ParentName).WithAlias(() => result.Name)
//this part does not work
 .Select(c => c.Children .Select(v => v.ChildName)).WithAlias(() => result.ChildrenNames) 
//                              
)
.TransformUsing(Transformers.AliasToBean<ParentDTO>());

return query.List<ParentDTO>();  

However I cant seem to be able to project the list of childName values into my ChildrenNames collection.

Any ideas?


Solution

  • As some guys said in comments, you need to do two queries. Using linq, you could try something like this:

    // get the parent Ids
    var parentIds = session.Query<Parent>().Select(c => c.Id).ToList(); 
    
    // get the childNames
    var childNames = session.Query<Child>()
                            .Where(x => parentIds.Contains(x.ParentId)) // get on the child from parents query
                            .Select(x => new {x.Name, x.ParentId}) // get only the properties you need
                            .ToList(); // list of anon objects
    
    // loop in memory between parentIds filling the corresponding childNames
    var result = parentIds.Select(parentId => new ParentDTO() 
                 { 
                    Id = parentId,
                    ChildrenNames = childNames.Where(x => x.ParentId == parentId).ToList()
                 }).ToList();
    

    I am not sure if it works, but you could try this in a single query:

    var query = from p in session.Query<Parent>()
                let names = p.Children.Select(c => c.ChildName).ToList()
                select new ParentDTO()
                {
                   Id = o.Id,
                   ChildrenNames = names
                };
    
    return query.Tolist();
    

    Obs: I did not test it.