我正在使用NHibernate 4和mysql。我有2张桌子。我的桌子是猫和答案。
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; }
}
我想选择所有猫记录(带答案列表)和他们的cild答案计数。
我这样的SQL查询;
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);
这样的结果;
id - catName - count
1 - Book - 5
2 - Pc - 0
3 - 英语 - 22
4 - 艺术 - 56
我也试过这个NH查询;
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>();
这个NHibernate查询返回也回答计数。但猫总是返回null。如何查询此结果?
修改1 我可以这样做
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();
答案 0 :(得分:0)
在您的结果中cats
始终为空,因为ResultTransformer
会尝试按名称映射属性。
请检查您的NHibernate日志文件。您可能会看到您的查询返回列count
和id
,但myClass
的属性为count
和cats
。
修改:
新建议:
之前的建议不起作用,因为属性id
的类型为Int32
,无法分配给myClass.cat
(类型为cat
)。
如果您不需要cat
中对myClass
- 对象的引用,那么您可以将其更改为:
public class myClass {
public virtual int count { get; set; }
public virtual int catId { get; set; }
}
并进行如下预测:
.Add(Projections.Group<cat>(g => g.id), "catId"));
如果您确实需要在结果类中使用cat
类型的属性,我不会认为这可以通过简单的投影完成,但我可能错了。
编辑2:
由于您在结果中需要cat
类型的对象,我建议您在查询后手动将其放在一起,例如:
新结果类:
public class myClassResult {
public virtual int count { get; set; }
public virtual cat cats { get; set; }
}
在查询逻辑后添加:
IList<myClassResult> result = new List<myClassResult>();
foreach (var idWithCount in list)
{
result.Add(new myClassResult()
{
cats = catsOnlyList.FirstOrDefault(x => x.id == idWithCount.catId),
count = idWithCount.count
});
}
catsOnlyList
是指您需要预先获得的简单猫咪名单。我知道这不是很好,但我认为你不能在查询中按cat
进行分组。
旧建议(由于类型不兼容而无效):
而不是
.Add(Projections.Group<cat>(g => g.id)));
使用
.Add(Projections.Group<cat>(g => g.id), "cats"));
答案 1 :(得分:0)
我可以这样做那个查询;
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();