NHibernate Criteria按另一个表中的groupid和itemid的总和选择项目

时间:2010-07-20 12:52:05

标签: nhibernate criteria aggregate nhibernate-projections

public class SearchText
{
    public virtual int Id { get; set; }
    public virtual string Text { get; set; }
}

public class SearchTextLog
{
    public virtual int Id { get; set; }
    public virtual SearchText SearchText { get; set; }
    public virtual User User { get; set; }
    public virtual int SearchCount { get; set; }
    public virtual DateTime LastSearchDate { get; set; }
}

我试图根据SearchTextLog中的计数总和选择前5个SearchText项目。目前我只能通过首先执行查询来获取前5个项目,然后在第二个查询中使用结果来解决此问题。我想知道是否有人可以向我展示灯光,并教我如何将这两个单独的查询整合到一个单元中。

以下是我目前的情况:

var topSearchCriteria = Session.CreateCriteria(typeof (SearchTextLog))
            .SetProjection(Projections.ProjectionList()
                            .Add(Projections.GroupProperty("SearchText.Id"))
                            .Add(Projections.Alias(Projections.Sum("SearchCount"), "SearchCount")))
            .AddOrder(Order.Desc("SearchCount"))
            .SetMaxResults(topSearchLimit)
            .List<int>();

return Session.CreateCriteria<SearchText>()
            .Add(Restrictions.In("Id", topSearchCriteria.ToArray()))
            .List<SearchText>();

修改

哦不,我刚刚意识到我当前的解决方案将失去结果的重要顺序。所以我肯定要合并查询。 : - /

修改

我也尝试了双向映射以允许以下语句,但是,我无法让它返回SearchText项。它只是抱怨SearchText属性不在分组中。

return Session.CreateCriteria<SearchText>()
                .CreateAlias("SearchTextLogs", "stl")
                .AddOrder(Order.Desc(Projections.Sum("stl.SearchCount")))
                .SetMaxResults(topSearchLimit)        
                .SetResultTransformer(Transformers.AliasToEntityMap)
                .List<SearchText>();

请原谅我的无知,但Nhibernate对我来说是全新的,需要一种完全不同的思维方式。

2 个答案:

答案 0 :(得分:14)

好的,我想我找到了解决方案。

根据我的问题,我的原始解决方案不起作用,因为NHibernate还不支持按属性执行分组而不将其添加到select子句的功能(请参阅:link text)。

然而,在愚弄时,我遇到了一些名为ResultTransformers的酷炫事物。使用AliasToBean结果转换器Nhibernate将自动将我给每个投影项的别名映射到我指定的类型中的相同名称的属性。我只是指定了我的SearchText对象(但是,我必须为sum投影项添加额外的TotalSearchCount属性)。它完美地填充了我的物品并将它们归还。

return Session.CreateCriteria(typeof(SearchTextLog))
            .CreateAlias("SearchText", "st")
            .SetProjection(Projections.ProjectionList()
                                .Add(Projections.Alias(Projections.GroupProperty("st.Id"), "Id"))
                                .Add(Projections.Alias(Projections.GroupProperty("st.Text"), "Text"))
                                .Add(Projections.Alias(Projections.Sum("SearchCount"), "TotalSearchCount")))
            .SetMaxResults(topSearchLimit)
            .AddOrder(Order.Desc("TotalSearchCount"))
            .SetResultTransformer(Transformers.AliasToBean(typeof(SearchText)))
            .List<SearchText>();

我很惊讶这不容易做到。我花了大约4到5个小时的时间进行研究并开发出来。希望通过越来越多的经验,我的NHibernate体验会变得更轻松。

我希望这可以帮助其他人!

答案 1 :(得分:1)

这不起作用吗?

var critterRes = Session.CreateCriteria(typeof (SearchTextLog))
            .SetProjection(Projections.ProjectionList()
                            .Add(Projections.GroupProperty("SearchText"))
                            .Add(Projections.Property("SearchText"))
                            .Add(Projections.Alias(Projections.Sum("SearchCount"), "SearchCount")))
            .AddOrder(Order.Desc("SearchCount"))
            .SetMaxResults(topSearchLimit)
            .List<SearchText>()