【问题标题】:Using a custom extension method in an Entity Framework GroupBy [duplicate]在实体框架 GroupBy 中使用自定义扩展方法 [重复]
【发布时间】:2021-03-04 07:12:10
【问题描述】:

在我的应用程序中,我在几个不同的地方计算几何平均值,并希望将实现放在一个地方,以减少维护者的困惑。出于性能原因,我需要在数据库中进行计算,因此不能在 C# 中获取数据并运行 GeoMean()

但是,我不知道如何编写可以在我的代码中使用的扩展方法。查询看起来像这样:

data.GroupBy(a => a.Foo)
    .Select(a => new {
        Id = a.Foo,
        Mean = a.GeoMean(b => b.Value)
    });  

我似乎已经确定我必须使用a.AsQueryable().GeoMean(),以及一个看起来像这样的扩展方法:

public static double GeoMean<T>(this IQueryable<T> source, Expression<Func<T, double>> fn)
{
    return Math.Exp(source.Average(i => Math.Log(fn(i))));
}

但是,由于预计会返回 double,因此它抱怨 fnExpression。如果我将返回类型更改为Expression&lt;Func&lt;double&gt;&gt;,我只是将问题移至查询中的Select,所以我可能需要对其做点什么,但是什么?

这甚至可能吗?我是否应该接受每次需要计算时都必须复制代码?

【问题讨论】:

标签: c# entity-framework-core


【解决方案1】:
public static double GeoMean<T>(this IQueryable<T> source, Expression<Func<T, double>> selector)
{
    var averageOfLogValues = source
        .Select(selector)
        .Select(value => Math.Log(value))
        .Average();

    return Math.Exp(averageOfLogValues);
}

【讨论】:

  • 问题是,在Select 内部,我有一个IGrouping,我不能简单地将其传递给GeoMean 并假装它是IQueryable(.AsQueryable 给出ArgumentException:类型的表达式IGrouping 不能用于 IQueryable 类型的参数)。
  • IGrouping 是一个单数“组”。它有一个键和可枚举的元素。 GroupBy 为您提供 IGrouping 的 IEnumerable/IQueryable。因此,您的选择器需要从分组本身中进行选择。除非您希望分组发生在 GeoMean 中?注意你的IDE的建议,它会对你有所帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-03-12
  • 2016-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多