4
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 对我来说是全新的,需要一种完全不同的思维方式。

4

2 回答 2

14

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

根据我的问题,我的原始解决方案不起作用,因为 NHibernate 尚不支持在不将其添加到 select 子句的情况下按属性进行分组的能力(请参阅:链接文本)。

然而,在闲逛的时候,我遇到了这些很酷的东西,叫做 ResultTransformers。使用 AliasToBean 结果转换器 Nhibernate 将自动将我给每个投影项的别名映射到我指定的类型中具有相同名称的属性。我只是指定了我的 SearchText 对象(但是,我必须为总和投影项添加一个额外的 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 体验会变得更轻松。

我希望这对其他人有帮助!

于 2010-07-21T14:49:09.217 回答
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>()
于 2010-07-20T17:44:02.190 回答