我正在开发一个共享库函数,它接受一个IQueryable和一个字段名称并为它生成聚合数字(min,max,sum,avgerage)。
我正在使用Entity Framework 5.0,.Net 4.5.1和Oracle 11g客户端软件连接到数据库。
我按如下方式生成动态表达式。
ParameterExpression parameter = Expression.Parameter(typeof(T), "x");
Expression body = Expression.PropertyOrField(parameter, field);
Type fieldFuncType = typeof(Func<,>).MakeGenericType(parameter.Type, body.Type);
LambdaExpression fieldLambdaExpression = Expression.Lambda(fieldFuncType, body, parameter);
var typedQuery = (IQueryable<Entities.TSD_ASSET>)query;
Expression<Func<T, double?>> fieldExpression = Expression.Lambda<Func<T, double?>>(Expression.Convert(fieldLambdaExpression.Body, typeof(double?)), fieldLambdaExpression.Parameters);
变量fieldExpression似乎与
的硬编码示例表达式匹配Expression<Func<Entities.TSD_ASSET, double?>> hardCodedExample = (Entities.TSD_ASSET entity) => (double?)entity.assetHours;
当T为Entities.TSD_ASSET且字段名称为&#34; assetHours&#34;。
我可以使用以下代码行运行单个查询聚合调用而无问题。
var temp2 = query.Max(fieldExpression);
但是如果我尝试使用下面的代码同时获取所有聚合,我会得到错误&#34;无法创建类型&#39; Entities.TSD_ASSET&#39;的常量值。在此上下文中仅支持基本类型或枚举类型。&#34;,并且运行的查询是来自tsd_asset查询的select *,而不是来自双交叉连接的select extent1._max,extent2._min(选择max()来自tsd_asset)extent1交叉连接(从tsd_asset中选择min())我在使用硬编码示例时看到的extent2类型查询。
var brokenQuery = owner.DUAL.Select(x => new {
_max = query.Max(fieldExpression),
_min = query.Min(fieldExpression),
_avg = query.Average(fieldExpression),
_sum = query.Sum(fieldExpression)
});
var v5 = brokenQuery.ToList();
注意:owner.DUAL是对SYS.DUAL表的EF引用。
在转换为我的示例类型后使用上面的硬编码表达式对查询工作正常。
var typedQuery = (IQueryable<Entities.TSD_ASSET>)query;
var workingQuery = owner.DUAL.Select(x => new {
max = typedQuery.Max(hardCodedExample),
min = typedQuery.Min(hardCodedExample),
avg = typedQuery.Average(hardCodedExample),
sum = typedQuery.Sum(hardCodedExample)
});
var v6 = workingQuery.ToList();
我的动态方法中缺少什么导致此类行为和错误?