为 NHibernate 中的 linq 生成平均时间跨度的方法
Generating a method for linq in NHibernate for avg timespan
我正在尝试在 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
有线索吗?
聚合表达式需要特殊处理,请参阅 MergeAggregatingResultsRewriter
. Unfortunately, this class is not injectable with more behavior, and the rewriter pipeline calls custom rewriters (see setting query.query_model_rewriter_factory
) too late (line 72), since aggregations needs to be handled before the group by rewriters (line 39)。
所有这些都适用于 NHibernate 5.1.2。
在我看来你使用的是低于 5 的版本,但你可能卡住了。
我认为如果不对 NHibernate 代码进行一些更改,您可能无法在 linq-to-nhibernate 中处理您的自定义 TimeSpan
平均值。
我正在尝试在 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
有线索吗?
聚合表达式需要特殊处理,请参阅 MergeAggregatingResultsRewriter
. Unfortunately, this class is not injectable with more behavior, and the rewriter pipeline calls custom rewriters (see setting query.query_model_rewriter_factory
) too late (line 72), since aggregations needs to be handled before the group by rewriters (line 39)。
所有这些都适用于 NHibernate 5.1.2。
在我看来你使用的是低于 5 的版本,但你可能卡住了。
我认为如果不对 NHibernate 代码进行一些更改,您可能无法在 linq-to-nhibernate 中处理您的自定义 TimeSpan
平均值。