我正在写一个转换IQueryable查询的访客。它使用带有种子Aggregatenull方法,然后使用一些func对其进行转换。我的问题是此null的类型为decimal?。但是我有一个异常(exception)

'Expression of type 'System.Object' cannot be used for parameter of type
'System.Nullable`1[System.Decimal]' of method 'System.Nullable`1[System.Decimal]
Aggregate[Nullable`1,Nullable`1]
(System.Linq.IQueryable`1[System.Nullable`1[System.Decimal]],
System.Nullable`1[System.Decimal],
System.Linq.Expressions.Expression`1[System.Func`3[System.Nullable`1[System.Decimal],
System.Nullable`1[System.Decimal],System.Nullable`1[System.Decimal]]])''

经过一番研究,我发现Aggregate本身破坏了我的查询:
public static TAccumulate Aggregate<TSource,TAccumulate>(this IQueryable<TSource> source, TAccumulate seed, Expression<Func<TAccumulate,TSource,TAccumulate>> func) {
    if (source == null)
        throw Error.ArgumentNull("source");
    if (func == null)
        throw Error.ArgumentNull("func");
    return source.Provider.Execute<TAccumulate>(
        Expression.Call(
            null,
            GetMethodInfo(Queryable.Aggregate, source, seed, func),
            new Expression[] { source.Expression, Expression.Constant(seed), Expression.Quote(func) }
            ));
}

我的问题是Expression.Constant(seed),它是null,而Expression.Constant将其转换为类型object的常量:
public static ConstantExpression Constant(object value) {
    return ConstantExpression.Make(value, value == null ? typeof(object) : value.GetType());
}

因此,我的new decimal?()转换为(object) null,并且出现此错误。

有什么解决方法吗?似乎无法在.net框架中进行修复(即使有可能,将在4.7或更高版本中进行修复)。我为此创建了一个拉取请求,但是我确定它不会被接受。

复制的代码段:
var result = new int?[] {1}.AsQueryable().Aggregate(default(int?), (a, b) => b);

最佳答案

从代码段开始复制

var result = new int?[] {1}.AsQueryable().Aggregate(default(int?), (a, b) => b);

我将其更改为
var result2 = new int?[] {1}.AsQueryable().DefaultIfEmpty().Aggregate((a, b) => b);

如果你想要一个等价的总和

空集合
var result3 = new int?[0].AsQueryable().DefaultIfEmpty().Aggregate(
   (a, b) => a.GetValueOrDefault() + b.GetValueOrDefault());

包含空值
var result4 = new int?[]{1,2,null}.AsQueryable().DefaultIfEmpty().Aggregate(
 (a, b) => a.GetValueOrDefault() + b.GetValueOrDefault());

基本上,我建议使用DefaultIfEmpty().Aggregate

关于c# - Queryable.Aggregate无法使用空值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42697311/

10-12 00:07