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对于CreatedCompletedDate属性具有相同的名称,所以我需要传递一个别名。但我无法设法让字符串别名形成正确的 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 回答