猿问

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

我正在尝试为 NHibernate 的 linq 中的时间跨度工作制作平均值。


我添加了注册表:


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


有什么线索吗?


largeQ
浏览 190回答 1
1回答

慕后森

聚合表达式需要特殊处理,请参阅MergeAggregatingResultsRewriter。不幸的是,这个类不能注入更多的行为,并且重写器管道调用自定义重写器(参见设置query.query_model_rewriter_factory)太晚(第 72 行),因为聚合需要在重写器组之前处理(第 39 行)。所有这些都适用于 NHibernate 5.1.2。在我看来,您使用的是低于 5 的版本,但您可能会遇到相同的情况。我认为您可能无法处理您的自定义TimeSpan平均值linq 到 nhibernate&nbsp;没有对 NHibernate 代码进行一些更改。
随时随地看视频慕课网APP
我要回答