c# - Queryable.Aggregate 不适用于空值

标签 c# .net linq iqueryable linq-expressions

我正在编写一个转换 IQueryable 查询的访问者。它使用带有种子 nullAggregate 方法,然后使用一些 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 将它转换为对象类型的常量:

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/

相关文章:

c# - 在 .NET 中使用 Firebase

c# - Enum.GetValues() 上的 OrderBy

c# - LINQ IEnumerable<T> 内存结构

C#/.NET : Reporting subprocess state to the parent service

c# - Sql Server LIKE 查询中需要转义哪些字符

c# - Windows 应用商店应用程序 (.NET) 上的 SSDP (UDP)

c# - Autofac - 无法创建请求生命周期范围,因为 HttpContext 不可用 - 由于异步代码?

c# - 如何在 C# 中将格式化的数字打印到屏幕上?

c# - 动态Where Linq 到实体

c# - 为什么 Task.Run 中的这种包装可以消除 ASP.NET Core 中的死锁?