在NHibernate中为平均时间跨度生成linq的方法

时间:2018-05-25 09:03:11

标签: c# linq nhibernate hql

我正试图在linq for NHibernate中为timepan工作做平均值。

我添加了注册表:

public class CustomLinqToHqlGeneratorsRegistry : DefaultLinqToHqlGeneratorsRegistry
{
    public CustomLinqToHqlGeneratorsRegistry()
    {
        this.Merge(new AvgTimeSpanGenerator());
    }
}

发电机:

public class AvgTimeSpanGenerator : BaseHqlGeneratorForMethod
{
     public AvgTimeSpanGenerator()
    {
        SupportedMethods = new[]
        {
             NHibernate.Linq.ReflectionHelper.GetMethodDefinition<IEnumerable<TimeSpan>>(x => x.Avg())
        };
    }

    public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor)
    {
        return treeBuilder.MethodCall("Avg", visitor.Visit(targetObject).AsExpression());
    }
}

请注意我的BuildHql实现可能不正确(实际上并没有真正考虑过),但我在那里设置了断点并且它永远不会被击中。

一种方法:

public static class NHibernateLinqExtension
{
    public static TimeSpan Avg(this IEnumerable<TimeSpan> timeSpan)
    {
        return new TimeSpan((long)timeSpan.Select(x => x.Ticks).Average());
    }
}

我还在NHibernate中注册了注册表:

configuration.LinqToHqlGeneratorsRegistry<CustomLinqToHqlGeneratorsRegistry>();

但是当我执行查询时:

var data = (from tcdr in uow.UnitOfWorkSession.Query<TCDR>()
                group tcdr.Duration by tcdr.Name into g
                select new
                {
                    MaxDuration = g.Max(),
                    MinDuration = g.Min(),
                    AvgDuration = g.Avg()
                }).ToList();

抛出InvalidOperationException Code supposed to be unreachable

有任何线索吗?

1 个答案:

答案 0 :(得分:1)

汇总表达式需要特殊处理,请参阅MergeAggregatingResultsRewriter。不幸的是,这个类不能注射更多行为,rewriter pipeline调用自定义重写器(请参阅setting query.query_model_rewriter_factorytoo late (line 72),因为需要在group by rewriters (line 39)之前处理聚合。 / p>

这一切都适用于NHibernate 5.1.2。

在我看来,你使用的版本低于5,但你的版本可能会相同。

我认为如果没有对NHibernate代码进行一些更改,您可能无法在中处理自定义的TimeSpan平均值。