I have two tables that have parent-child relationships. I want to count the records of a child table, grouping them by parent and collecting the results. So I want to see how many times each parent object is referenced in a child table.
So, if my parent table is Cats:
| Id | Name |
| 1 | Bob |
| 2 | Garfield |
and the child table is CatSkills:
| Id | Cat_Id | Skill |
| 1 | 1 | Land on feet |
| 2 | 2 | Eat lasagne |
| 3 | 2 | Escape diets |
I want to get the following:
| Id | Name | count of skills |
| 1 | Bob | 1 |
| 2 | Garfield | 2 |
I tried with NHibernate LINQ, the query seems correct, but I get an exception "function not supported".
I tried with NHibernate QueryOver, there I get N + 1 problem:
var q = Session.QueryOver<CatSkill>()
.Fetch(s => s.Cat).Eager
.Select(Projections.ProjectionList()
.Add(Projections.Group<CatSkill>(s => s.Cat))
.Add(Projections.RowCount()))
.List<object[]>();
The above query works, but it will retrieve all the parent records in separate queries.
SQL , SELECT GROUP BY.
- , ? !
, Radim, :
class CatDto : Cat
{
public int Count { get; set; }
}
Cat parent = null;
CatSkill child = null;
CatDto dto = null;
var subQuery = QueryOver.Of<CatSkill>(() => child)
.Where(() => child.Cat.ID == parent.ID)
.Select(Projections.RowCount());
var skillFilterSubQuery = QueryOver.Of<CatSkill>(() => child)
.Where(() => child.Cat.ID == parent.ID )
.Select(p => p.Cat);
var query = session.QueryOver<Cat>(() => parent);
query = query.WithSubquery.WhereExists(skillFilterSubQuery);
query.SelectList(l => l
.Select(p => p.ID).WithAlias(() => dto.ID)
.Select(p => p.Name).WithAlias(() => dto.Name)
.Select(Projections.SubQuery(subQuery)).WithAlias(() => dto.Count));
query.TransformUsing(Transformers.AliasToBean<CatDto>());
return query.List<CatDto>();
, N + 1, (Cat ) DTO.
, .Select(s => s), Exception, "".