如何使用 NHibernate 的 ICriteria 进行分组、获取关联和 T-SQL 函数
我想创建以下 T-SQL 语句:
SELECT SUM (sa.Amount) as 'SumAmount',
SUM(sa.Cost) as 'SumCost',
gg.[Description] as 'Goodsgroup', Month(sa.[Date]) as 'Month'
FROM SalesmanArticle sa
INNER JOIN Article a
ON a.ArticleId = sa.ArticleId
INNER JOIN GoodsGroup gg
ON gg.GoodsGroupId = a.GoodsGroupId
GROUP BY gg.[Description], Month(sa.[Date])
ORDER BY 'Month', 'Goodsgroup'
Is this possible with NHibernates ICriteria?
如何使用 Month-T-SQL-Function?
我是否必须手动加入,或者 ICriteria API 是否知道当我使用 propetyName“SalesmanArticle.Article.Goodsgroup.Description”时,它必须加入文章和商品组?
编辑:
现在我已经在这里编写了这段代码:
// typesafe properties
string article = typeof(Article).Name;
string goodsGroup = typeof(GoodsGroup).Name;
string salesmanArticle = typeof(SalesmanArticle).Name;
string amount = Reflector.GetPropertyName<SalesmanArticle>(x => x.Amount);
string cost = Reflector.GetPropertyName<SalesmanArticle>(x => x.Cost);
string description = string.Format("{0}.{1}",
goodsGroup, Reflector.GetPropertyName<SalesmanArticle>(x => x.Article.GoodsGroup.Description));
string date = Reflector.GetPropertyName<SalesmanArticle>(x => x.Date);
string formatedDate = string.Format("MONTH([{0}])", date);
return GetSession()
// FROM
.CreateCriteria(typeof(SalesmanArticle), salesmanArticle)
// JOIN
.CreateCriteria(article, article, JoinType.InnerJoin)
.CreateCriteria(goodsGroup, goodsGroup, JoinType.InnerJoin)
// SELECT
.SetProjection(Projections.ProjectionList()
.Add(Projections.Sum(amount))
.Add(Projections.Sum(cost))
// GROUP BY
.Add(Projections.GroupProperty(description))
.Add(Projections.SqlGroupProjection(formatedDate, formatedDate, new[]{"MyDate"} , new[] { NHibernateUtil.Int32 })))
.List();
但是抛出了 AdoException:
无法执行查询[ SELECT sum(this_.Amount) 作为 y0_, sum(this_.Cost) 作为 y1_, 货物组2_。描述为y2_, 月([日期])来自 [销售员文章] this_内连接【文章】article1_ 关于这个_.ArticleId=article1_.ArticleId 内部联接 [GoodsGroup]goodsgroup2_ 在 Article1_.GoodsGroupId=goodsgroup2_.GoodsGroupId GROUP BYgoodsgroup2_.描述, 月([日期])]
[SQL: 选择 sum(this_.Amount) 作为 y0_, sum(this_.Cost) 作为 y1_, 货物组2_。描述为y2_, 月([日期])来自 [销售员文章] this_内连接【文章】article1_ 关于这个_.ArticleId=article1_.ArticleId 内部连接 [GoodsGroup]goodsgroup2_ 在 Article1_.GoodsGroupId=goodsgroup2_.GoodsGroupId GROUP BYgoodsgroup2_.描述, 月([日期])]
奇怪的是 NHibernate 尝试创建 2 个查询?!
他们都是正确的!
代码行
.Add(Projections.SqlGroupProjection(formatedDate, formatedDate, new[]{"MyDate"} , new[] { NHibernateUtil.Int32 })))
而不是我使用的
.Add(Projections.SqlFunction("MONTH", NHibernateUtil.Int32, Projections.GroupProperty(date))))
SqlFunction 的问题是它创建了一个 GROUP BY sa.Date 而不是 MONTH(sa.Date)。但这种方法在语法上是正确的。
所以我切换到SqlGroupProjection方法。
但无论如何它都不起作用。
有人可以帮助我吗?
I want to create the following T-SQL statement:
SELECT SUM (sa.Amount) as 'SumAmount',
SUM(sa.Cost) as 'SumCost',
gg.[Description] as 'Goodsgroup', Month(sa.[Date]) as 'Month'
FROM SalesmanArticle sa
INNER JOIN Article a
ON a.ArticleId = sa.ArticleId
INNER JOIN GoodsGroup gg
ON gg.GoodsGroupId = a.GoodsGroupId
GROUP BY gg.[Description], Month(sa.[Date])
ORDER BY 'Month', 'Goodsgroup'
Is this possible with NHibernates ICriteria?
How can I use the Month-T-SQL-Function?
Do I have to join manually or does the ICriteria API knows that when I use the propetyName 'SalesmanArticle.Article.Goodsgroup.Description' it has to join the Article and the Goodsgroup?
EDIT:
For now I have written this code here:
// typesafe properties
string article = typeof(Article).Name;
string goodsGroup = typeof(GoodsGroup).Name;
string salesmanArticle = typeof(SalesmanArticle).Name;
string amount = Reflector.GetPropertyName<SalesmanArticle>(x => x.Amount);
string cost = Reflector.GetPropertyName<SalesmanArticle>(x => x.Cost);
string description = string.Format("{0}.{1}",
goodsGroup, Reflector.GetPropertyName<SalesmanArticle>(x => x.Article.GoodsGroup.Description));
string date = Reflector.GetPropertyName<SalesmanArticle>(x => x.Date);
string formatedDate = string.Format("MONTH([{0}])", date);
return GetSession()
// FROM
.CreateCriteria(typeof(SalesmanArticle), salesmanArticle)
// JOIN
.CreateCriteria(article, article, JoinType.InnerJoin)
.CreateCriteria(goodsGroup, goodsGroup, JoinType.InnerJoin)
// SELECT
.SetProjection(Projections.ProjectionList()
.Add(Projections.Sum(amount))
.Add(Projections.Sum(cost))
// GROUP BY
.Add(Projections.GroupProperty(description))
.Add(Projections.SqlGroupProjection(formatedDate, formatedDate, new[]{"MyDate"} , new[] { NHibernateUtil.Int32 })))
.List();
But an AdoException is thrown:
could not execute query [ SELECT
sum(this_.Amount) as y0_,
sum(this_.Cost) as y1_,
goodsgroup2_.Description as y2_,
MONTH([Date]) FROM [SalesmanArticle]
this_ inner join [Article] article1_
on this_.ArticleId=article1_.ArticleId
inner join [GoodsGroup] goodsgroup2_
on
article1_.GoodsGroupId=goodsgroup2_.GoodsGroupId
GROUP BY goodsgroup2_.Description,
MONTH([Date]) ][SQL: SELECT
sum(this_.Amount) as y0_,
sum(this_.Cost) as y1_,
goodsgroup2_.Description as y2_,
MONTH([Date]) FROM [SalesmanArticle]
this_ inner join [Article] article1_
on this_.ArticleId=article1_.ArticleId
inner join [GoodsGroup] goodsgroup2_
on
article1_.GoodsGroupId=goodsgroup2_.GoodsGroupId
GROUP BY goodsgroup2_.Description,
MONTH([Date])]
The strange thing is that NHibernate tries to create 2 queries?!
AND BOTH of them are correct!
Instead of the codeline
.Add(Projections.SqlGroupProjection(formatedDate, formatedDate, new[]{"MyDate"} , new[] { NHibernateUtil.Int32 })))
I used
.Add(Projections.SqlFunction("MONTH", NHibernateUtil.Int32, Projections.GroupProperty(date))))
The problem with the SqlFunction is that it creates a GROUP BY sa.Date instead of MONTH(sa.Date). But this method worked syntactically correct.
So I switched to the SqlGroupProjection method.
But anyway it does not work.
Can anybody help me?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我解决了。这是正确的代码:
I solved it. Here is the correct code: