NHibernate:hql到条件查询 - 需要帮助

时间:2009-09-17 12:34:58

标签: c# nhibernate

我有这个hql查询,它完美无缺:

            select m 

            from Media m

            join m.Productlines p
            join m.Categories c                
            join m.Spaces sp
            join m.Solutions so

            where m.Uid != 0
            and p.Uid in (:productlines)
            and c.Uid in (13)                
            and sp.Uid in (52)
            and so.Uid in (15,18)

            group by m.Uid

但现在它需要参数化/制作动态,不仅是参数,还有连接(可以只从Media中选择,没有任何连接,因此在这种情况下不需要* .Uid in )。

我不想乱用StringBuilder实例并以这种方式构建hql查询,我宁愿使用Criteria API,但我无法获得

SELECT m.*
....
GROUP BY m.Uid

查询以使用Criteria。

如果我添加

Projections.GroupProperty("Uid") 

到我的查询,nhibernate选择

SELECT m.Uid
....
GROUP BY m.Uid

当然是错的。

之后,我还需要计算查询返回的唯一行,因为结果是分页的。

所以,我的其他查询非常类似,但我找不到

的Criteria等价物
SELECT COUNT(DISTINCT m.Uid)

这是HQL:

            select count(distinct m.Uid) 

            from Media m

            join m.Productlines p
            join m.Categories c                
            join m.Spaces sp
            join m.Solutions so

            where m.Uid != 0
            and p.Uid in (:productlines)
            and c.Uid in (13)                
            and sp.Uid in (52)
            and so.Uid in (15,18)

如何使用Criteria API完成此操作?

请,(N)Hibernate专家 - 帮助我,我找不到一个有效的解决方案。非常感谢任何帮助!

2 个答案:

答案 0 :(得分:2)

组结果列隐式返回,但您可以添加更多列。 AFAIK,您可以返回完整的实体:

var query = session.CreateCriteria(typeof(Media), "m")
  .Add(Projections.GroupProperty("m"))
  .Add(Restrictions.NotEq("m.Uid", 0));

// dynamically add filters
if (filterProductLines)
{
  query
    .CreateCriteria("m.Productlines", "p")
    .Add(Restrictions.Eq("p.Uid", productLines));
}
// more dynamic filters of this kind follow here...

IList<Media> results = query.List<Media>();

要计算完整数量的结果,您可以使用不同的投影构建相同的查询:

var query = session.CreateCriteria(typeof(Media), "m")
    .SetProjection(Projections.CountDistinct("m.Uid"));
// rest of the query the same way as above

long totalNumberOfResults = query.UniqueResult<long>();

我对Projections.GroupProperty("m")不确定,你需要尝试这个。如果它不起作用,你可以使它成为只返回ids的DetachedQuery:

var subquery = DetachedCriteria.For(typeof(Media), "m")
  .Add(Projections.GroupProperty("m.Uid"))
  .Add(Restrictions.NotEq("m.Uid", 0));
// add filtering

var query = session.CreateCriteria(typeof(Media), "outer")
  .Add(Subqueries.PropertyIn("outer.Uid", subquery));

IList<Media> results = query.List<Media>();

这会创建一个像这样的SQL查询:

select outer.* // all properties of Media to create an instance
from Media outer
where outer.Uid in (
  select Uid
  from media m
  where // filter
)

答案 1 :(得分:1)

var count = session.CreateCriteria(typeof(Media))
    // Add other criterias...
    .SetProjection(Projections.CountDistinct("Id")) // or whatever the id property of Media class is called
    .UniqueResult<long>();

关于您的GROUP BY问题,查询:

SELECT m.*
....
GROUP BY m.Uid

没有意义,因为您只需要选择group by子句或聚合函数中出现的列。你能详细说明你到底想要达到的目标吗?