0

NHibernate 3.3.3.4000 プロジェクトでグループ化とカウントを使用して要約クエリを作成しています。多対多の関係を持つドメイン オブジェクトPositionとがあります。Tag1 つの位置には少数のタグがありますが、時間の経過とともに各タグに多数の位置が存在するようになります。したがって、関係は一方向で、Position にはタグのコレクションがありますが、その逆はありません。

AcademicTerm私のクエリは、特定の(位置のスカラー参照) に接続されている位置について、各タグで位置の数をカウントアップします。以下のクエリは機能します。

    public IPartialResult<TagSummary> GetTagSummaries(string termCode, int skip, int take)
    {
        Tag tagAlias = null;
        AcademicTerm termAlias = null;
        TagSummary summary = null;

        var tagQuery = Session.QueryOver<Position>()
            .JoinAlias(p => p.Term, () => termAlias)
            .Where(() => termAlias.TermCode == termCode)
            .JoinQueryOver<Tag>(t => t.Tags, () => tagAlias)
            .SelectList(projections => projections
                .SelectGroup(p => tagAlias).WithAlias(() => summary.Tag)
                .SelectCount(p => p.ID).WithAlias(() => summary.PositionCount))     
            .TransformUsing(Transformers.AliasToBean<TagSummary>());

        var countQuery = tagQuery.ToRowCountQuery().FutureValue<int>();

        var resultQuery = tagQuery
            .OrderBy(t => t.Name).Asc
            .Skip(skip)
            .Take(take)
            .Future<TagSummary>();

        return new PartialResult<TagSummary>(resultQuery, countQuery.Value);

結果のタイプはTagSummary次のとおりです。

public class TagSummary
{
    public string TagName { get; set; }
    public int PositionCount { get; set; }
}

そこにあるのは Tag の Name プロパティですが、私が本当に欲しいのは Tag そのものです。その方法がわかりません。権利はありますがtagAlias、TagSummary に入れる方法がわかりません。の個々のプロパティを選択する必要がありますTagか? タグの ID 値を選択して、別のクエリを実行することもできますが、あまりうまくいきません。

更新グループ化が取り除かれる ため、カウントクエリが機能しないことToRowCountQueryがわかりました。今、私はそれを解決しようとしています。

4

1 に答える 1

0

私自身の質問に答えるために、最終的に、 count プロパティを追加するTagcalledのサブクラスを作成しました。SummarizedTag次に、クエリを変更して、 の個々のプロパティをすべて選択し、カウントを計算してから、それらをsTagに水和しました。SummarizedTagそれらは のサブクラスであるためTag、ビューでそれらを処理する方が少しきれいです。にさらにプロパティを追加する場合は、クエリを更新する必要がありますTag。それは避けられないようです。

グループ化されたクエリでページングを処理するには、最初のクエリで使用するのではなく、「手動で」2 番目のクエリを作成する必要がToRowCountQuery()ありました。

public IPartialResult<SummarizedTag> GetSummarizedTags(string termCode, int skip, int take)
    {
        Logger.DebugFormat("GetSummarizedTags: termCode={0}, skip={1}, take={2}", termCode, skip, take);

        Tag tagAlias = null;
        AcademicTerm termAlias = null;
        SummarizedTag summary = null;

        // Get all tags attached to positions in specified term, with their use counts
        var tagQuery = Session.QueryOver<Position>()
            .Where(p => p.Status == PositionStatus.Published)
            .JoinAlias(p => p.Term, () => termAlias)
            .Where(() => termAlias.TermCode == termCode)
            .JoinQueryOver<Tag>(t => t.Tags, () => tagAlias)
            .SelectList(projections => projections
                .SelectGroup(() => tagAlias.ID).WithAlias(() => summary.ID)
                .SelectGroup(() => tagAlias.Name).WithAlias(() => summary.Name)
                .SelectGroup(() => tagAlias.Active).WithAlias(() => summary.Active)
                .SelectGroup(() => tagAlias.Description).WithAlias(() => summary.Description)
                .SelectGroup(() => tagAlias.UrlFormatName).WithAlias(() => summary.UrlFormatName)
                .SelectCountDistinct(p => p.ID).WithAlias(() => summary.Count))
            .TransformUsing(Transformers.AliasToBean<SummarizedTag>())
            .OrderByAlias(() => summary.Count).Desc
            .Skip(skip)
            .Take(take)
            .Future<SummarizedTag>();

        // Count tags used in positions in specified term.
        var countQuery = Session.QueryOver<Position>()
            .JoinAlias(p => p.Term, () => termAlias)
            .Where(() => termAlias.TermCode == termCode)
            .JoinQueryOver<Tag>(p => p.Tags, () => tagAlias)
            .Select(Projections.CountDistinct(() => tagAlias.ID))
            .FutureValue<int>();

        return new PartialResult<SummarizedTag>(tagQuery, countQuery.Value);
    }
于 2013-09-18T18:32:27.113 に答える