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 項目を取得し、その結果を 2 番目のクエリで使用することによってのみ、これを解決できました。誰かが私に光を見せて、これら 2 つの別々のクエリを 1 つのユニットに統合する方法を教えてくれないかと思っていました。

これが私が現在持っているものです:

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 に答える