entity-framework - 将聚合选择表达式传递给 Dynamic Linq 的 GroupBy
问题描述
我已经从我的代码中简化了以下示例,并希望没有明显的编译错误。假设我有以下实体(不是我实际拥有的,请假设我没有 EF 或架构问题,这只是示例):
public class Company
{
public string GroupProperty {get;set;}
public virtual ICollection<PricingForm> PricingForms {get;set;}
}
public class PricingForm
{
public decimal Cost {get;set;}
}
我想这样查询:
IQueryable DynamicGrouping<T>(IQueryable<T> query)
{
Expression<Func<Company, decimal?>> exp = c => c.PricingForms.Sum(fr => fr.Cost);
string selector = "new (it.Key as Key, @0(it) as Value)";
IQueryable grouping = query.GroupBy("it.GroupProperty", "it").Select(selector, exp);
return grouping;
}
调用 groupby/select 行时出现以下错误:
System.Linq.Dynamic.ParseException: 'Argument list incompatible with lambda expression'
分组时“它”是什么类型?我尝试使用其他表达式,假设它是一个IGrouping<string, Company>
或一个IQueryable<Company>
相同的错误。我试过只选择“成本”并将 Sum() 聚合移动到选择器字符串(即Sum(@0(it)) as Value
)中,但似乎总是得到相同的错误。
我最终尝试了一些类似的东西:
Expression<Func<IEnumerable<Company>, decimal?>> exp = l => l.SelectMany(c => c.PricingForms).Sum(fr => fr.Cost);
然而,这一次,我走得更远,但是当尝试遍历结果时,我得到了一个不同的错误。
The LINQ expression node type 'Invoke' is not supported in LINQ to Entities.
那么,通过这种动态分组并注入我自己的选择表达式,我应该假设“它”的数据类型是什么?这甚至会起作用吗?
解决方案
的类型it
是IGrouping<TKey, TElement>
,其中TKey
根据keySelector
结果类型是动态的,TElement
是 input 的元素类型IQueryable
。幸运的是IGrouping<TKey, TElement>
继承了 (is a) IEnumerable<TElement>
,因此一旦您知道输入元素类型,您就可以安全地将选择器基于IEnumerable<TElement>
.
换句话说,基于的最后一次尝试Expression<Func<IEnumerable<Company>, decimal?>>
是正确的。
您收到的新错误是因为@0(it)
生成Expression.Invoke
了 EF 不支持的调用。解决这个问题的最简单方法是使用LINQKit Expand
方法:
Expression<Func<Company, decimal?>> exp = c => c.PricingForms.Sum(fr => fr.Cost);
string selector = "new (it.Key as Key, @0(it) as Value)";
IQueryable grouping = query.GroupBy("it.GroupProperty", "it").Select(selector, exp);
// This would fix the EF invocation expression error
grouping = grouping.Provider.CreateQuery(grouping.Expression.Expand());
return grouping;
推荐阅读
- typescript - 为接口的函数属性实现泛型类型
- pine-script - 在一个 Tradingview 脚本中跨多个时间范围发出警报
- google-apps-script - Google 脚本无法在移动设备上运行
- c# - 子类上的 Insight.Database [BindChildren] 不起作用
- node.js - 使用 sinon chai 和 mocha 在 nodejs 中测试服务
- maven - Command line mvn missing dependency
- c++ - C ++ ifstream在它(据说)到达eof之后读取文件
- amazon-web-services - 云形成漂移和变化集有什么区别?
- javascript - 无法读取未定义的属性,运行时错误
- mysql - 需要使用 laravel 控制器插入数组数据