Search code examples
c#mysqlnhibernatefluent-nhibernatesql-to-linq-conversion

NHibernate parent list with child count


i am using NHibernate 4 with mysql. i have got 2 tables. My tables are cat and answer.

public class cat
{
    [Key]
    public virtual int id { get; set; }
    public virtual string catName { get; set; }

    public virtual IList<answer> answers { get; set; }
}

public class answer
{
    [Key]
    public virtual int id { get; set; }
    public virtual int catId { get; set; }
    public virtual string detail { get; set; }
    public virtual bool stat { get; set; }

    [ForeignKey("catId")]
    public virtual cat cats { get; set; }
}

i want to select all cat record(with answer list) and with their cild answers count.

my sql query like that;

select count(t2.id) as count, cats.*from cat cats left join answer t2 ON(cats.id=t2.catId and t2.stat=0) GROUP BY(cats.id);

Result like this;

id - catName - count

1 - Book - 5

2 - Pc - 0

3 - English - 22

4 - Arts - 56

i have try also this NH query;

public class myClass {
  public virtual int count { get; set; }
  public virtual cat cats { get; set; }
}

var u = db.CreateCriteria(typeof(cat), "cats")
       .CreateAlias("answer", "t2", NHibernate.SqlCommand.JoinType.LeftOuterJoin, Restrictions.Eq("t2.stat", false))
      .SetProjection(Projections.ProjectionList()
      .Add(Projections.Count("t2.id"), "count")
      .Add(Projections.Group<cat>(g => g.id)));


var list = u.SetFetchMode("answer", FetchMode.Eager)
        .SetResultTransformer(Transformers.AliasToBean<myClass>())
        .List<myClass>();

This NHibernate query return also answers count. but cats always return null. How can i do my query for this result ?

Edit 1 i can do it like that

public class myClass {
  public virtual int count { get; set; }
  public virtual catId count { get; set; }
  public virtual cat cats { get; set; }
}


cat cats = null;
answer answers = null;

var u = db.QueryOver<cat>(() => cats)
    .JoinQueryOver(x => x.answers, () => answers, NHibernate.SqlCommand.JoinType.LeftOuterJoin, Restrictions.Eq("answers.stat", false))
    .SelectList(cv => cv
        .SelectCount(() => answers.id)
        .SelectGroup(c => c.id))
    .List<object[]>()
    .Select(ax => new myClass
    {
      count = (int)ax[0],
      catId = (int)ax[1],
      cats = (cat)db.QueryOver<cat>().Where(w=>w.id==(int)ax[1]).Fetch(fe => fe.answers).Eager.SingleOrDefault()
    })
    .ToList();

Solution

  • i can do that query like that;

    public class myClass {
      public virtual int count { get; set; }
      public virtual İnt catId { get; set; }
      public virtual cat cats { get; set; }
    }
    
    cat cats = null;
    answer answers = null;
    
    var u = db.QueryOver<cat>(() => cats)
        .JoinQueryOver(x => x.answers, () => answers, NHibernate.SqlCommand.JoinType.LeftOuterJoin, Restrictions.Eq("answers.stat", false))
        .SelectList(cv => cv
            .SelectCount(() => answers.id)
            .SelectGroup(c => c.id))
        .List<object[]>()
        .Select(ax => new myClass
        {
          count = (int)ax[0],
          catId = (int)ax[1],
          cats = (cat)db.QueryOver<cat>().Where(w=>w.id==(int)ax[1]).Fetch(fe=>fe.answers).Eager.SingleOrDefault()
        })
        .ToList();