bugfix> c# > 投稿

NHibernateのlinqでタイムスパンのavgを機能させようとしています。

レジストリを追加しました:

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 件
  • 式の集計には特別な処理が必要です。 MergeAggregatingResultsRewriter を参照してください 。残念ながら、このクラスはより多くの動作を伴う注入可能ではなく、リライタパイプラインはカスタムリライタを呼び出します( query.query_model_rewriter_factory の設定を参照) )集計がリライタによってグループの前に処理される必要があるため(行72)、遅すぎます(行72)。

    これはすべて、NHibernate 5.1.2に適用されます。

    あなたは5より前のバージョンを使用しているように見えますが、おそらく同じままです。

    カスタム TimeSpan を処理できるとは思わない  NHibernateコードに変更を加えずにlinq-to-nhibernateで平均します。

あなたの答え