实体框架5.0动态聚合字段表达式

时间:2017-01-05 19:25:52

标签: c# oracle entity-framework lambda expression

我正在开发一个共享库函数,它接受一个I​​Queryable和一个字段名称并为它生成聚合数字(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();

我的动态方法中缺少什么导致此类行为和错误?

0 个答案:

没有答案