4

次の集計クエリがあります:

   IQueryOver<CustomerTask, CustomerTask> query = GetSession().QueryOver(() => task)
    .JoinAlias(() => task.TaskList, () => taskList)
    .JoinAlias(() => task.TaskChain, () => taskChain)
    .Where(() => taskList.SalesFlow == salesFlow)
    .Select(
        Projections.Group(() => taskList.Id)
            .WithAlias(() => salesFlowTaskStatisticsGridRow.RowId),
        Projections.Group(() => taskList.SalesFlow.Id)
            .WithAlias(() => salesFlowTaskStatisticsGridRow.SalesFlowId),
        Projections.Group(() => taskList.Name).WithAlias(() => salesFlowTaskStatisticsGridRow.Name),
        // ReSharper disable ExpressionIsAlwaysNull
        criteriaBuilder.FindAverageCompletionTime(salesFlowTaskStatisticsGridRow)
    // ReSharper restore ExpressionIsAlwaysNull
    ).TransformUsing(Transformers.AliasToBean<SalesFlowTaskStatisticsGridRow>());

平均時間を数えるには、それを書くためにdatediff関数を呼び出す必要があるので、私はSqlProjectionを使用します

    private static AggregateProjection CountAverageCompletionTimeForTasksCriteria()
    {
        return Projections.Avg(Projections
            .SqlProjection("datediff(ss, Created, CompletedDate) as CompletionTimeInSeconds",
                new[] {"CompletionTimeInSeconds"}, new[] {NHibernateUtil.Double}));
    }

問題は、TaskTaskChainの両方がCreatedプロパティとCompletedDateプロパティの名前が同じであるため、エイリアスを渡す必要があることです。しかし、文字列エイリアスを取得して正しいSQLプロジェクションを形成することはできません。これらのエイリアスを取得する方法はありますか、それとも他の方法でdatediff関数をクエリに固定できますか?

4

1 に答える 1

0

NHibernate は、SqlProjection を使用するときにエイリアスを処理するための洗練されたオプションをあまり提供していません。

唯一の回避策は、最初に datediff プロジェクションを使用せずにクエリをプロファイリングし、NHibernate が Task と TaskChain に使用しているエイリアスを確認することです (おそらくthis_と *this_1* のようなものになります)。次に、これらのエイリアスを次のようにプロジェクションに手動でハードコードできます。

.SqlProjection("datediff(ss, this_.Created, this_.CompletedDate) as CompletionTimeInSeconds",
                new[] {"CompletionTimeInSeconds"}, new[] {NHibernateUtil.Double})

明らかに、これは完璧にはほど遠いですが、うまくいくでしょう。

于 2012-09-21T13:30:38.987 に答える