带有子计数的 NHibernate 父列表
NHibernate parent list with child count
我在 mysql 中使用 NHibernate 4。我有 2 张桌子。我的表是 cat 和 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; }
}
我想 select 所有猫记录(带答案列表)和他们的 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 - 计数
1 - 书 - 5
2 - 电脑 - 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 查询 return 也回答了计数。但是猫总是 return 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();
在您的结果中 cats
始终为 null,因为 ResultTransformer
试图通过名称映射属性。
请检查您的 NHibernate 日志文件。您可能会看到您的查询 returns 列 count
和 id
,但是 myClass
具有属性 count
和 cats
.
编辑:
新建议:
之前的建议没有用,因为属性 id
是Int32
类型,不能赋值给myClass.cat
(cat
类型=]).
如果您不需要对 myClass
中的 cat
对象的引用,那么您可以将其更改为:
public class myClass {
public virtual int count { get; set; }
public virtual int catId { get; set; }
}
并有这样的投影:
.Add(Projections.Group<cat>(g => g.id), "catId"));
如果您确实需要 属性 类型 cat
在您的结果中 class 我不认为这可以通过简单的投影来完成,但我可能是错的。
编辑 2:
由于您在结果中需要类型为 cat
的对象,我建议您在查询后手动将其组合在一起,例如:
新结果class:
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"));
我可以这样查询;
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();
我在 mysql 中使用 NHibernate 4。我有 2 张桌子。我的表是 cat 和 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; }
}
我想 select 所有猫记录(带答案列表)和他们的 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 - 计数
1 - 书 - 5
2 - 电脑 - 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 查询 return 也回答了计数。但是猫总是 return 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();
在您的结果中 cats
始终为 null,因为 ResultTransformer
试图通过名称映射属性。
请检查您的 NHibernate 日志文件。您可能会看到您的查询 returns 列 count
和 id
,但是 myClass
具有属性 count
和 cats
.
编辑:
新建议:
之前的建议没有用,因为属性 id
是Int32
类型,不能赋值给myClass.cat
(cat
类型=]).
如果您不需要对 myClass
中的 cat
对象的引用,那么您可以将其更改为:
public class myClass {
public virtual int count { get; set; }
public virtual int catId { get; set; }
}
并有这样的投影:
.Add(Projections.Group<cat>(g => g.id), "catId"));
如果您确实需要 属性 类型 cat
在您的结果中 class 我不认为这可以通过简单的投影来完成,但我可能是错的。
编辑 2:
由于您在结果中需要类型为 cat
的对象,我建议您在查询后手动将其组合在一起,例如:
新结果class:
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"));
我可以这样查询;
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();