【问题标题】:MVC linq to sql sumMVC linq to sql sum
【发布时间】:2016-01-22 16:58:57
【问题描述】:

尝试根据字段的总和从数据库中获取返回的值。

但收到此消息:

转换为值类型“System.Decimal”失败,因为 物化值为空。结果类型的泛型参数 或者查询必须使用可为空的类型。

数据库不包含该用户当天的记录是有效的,因此我选择了可​​以为空的路线。在过去的美好时光里,我会构建一个包含 `ISNULL` 的存储过程!!!

这是我的基本表达方式:

decimal? foodCount = dbContext.fad_userFoods.Where(uf => uf.dateAdded == thisDate && uf.userID == thisGuid).Sum(uf=>(decimal?)uf.quantityAmount ?? 0m);

谷歌搜索它想出了可以为空的定义和使用 ??用“m”,因为它是十进制的。但是错误仍然存​​在!

您的集体帮助将一如既往地无价。提前致谢。

【问题讨论】:

    标签: c# asp.net-mvc linq decimal nullable


    【解决方案1】:

    使用DefaultIfEmpty 方法。如果根本找不到任何值,这将填充 0。

    decimal foodCount = dbContext.fad_userFoods
        .Where(uf => uf.dateAdded == thisDate && uf.userID == thisGuid)
        .Select(uf => uf.quantityAmount)
        .DefaultIfEmpty()
        .Sum();
    

    【讨论】:

    • 宾果游戏!感谢 Maarten,这成功了。在 linq to sql 上还有很多东西要学!
    【解决方案2】:

    既然是sum 而不是average,你真的不介意空值吗? 为什么不简单地删除空值?

        decimal? foodCount = dbContext.fad_userFoods
          .Where(uf => 
             uf.dateAdded == thisDate && 
             uf.userID == thisGuid && 
             uf.quantityAmount != null)
          .Sum(uf=> uf.quantityAmount);
    

    【讨论】:

    • 基本上我正在寻找某人一天吃过的某些食物。所以可能是那个人没有吃过那些食物,因此数量的总和将为0,因为它们不存在于桌子上。
    • 是的,但是在这种情况下,null应该被转换为0,这等于根本不计算它。因此,在 where 子句中排除它会完全避免问题,但仍会给出相同的金额。此外,它还避免了数据库中的任何类型转换。
    【解决方案3】:

    使用Convert.ToDecimal(),这将处理您的空问题。

    decimal foodCount = dbContext.fad_userFoods.Where(uf => uf.dateAdded == thisDate 
                                                         && uf.userID == thisGuid)
                                               .Sum(uf=> Convert.ToDecimal(uf.quantityAmount ?? 0m));
    

    LINQ to Entities 无法识别方法 'System.Decimal ToDecimal(System.Decimal)' 方法,并且该方法不能 翻译成商店表达式。

    编辑:

    decimal foodCount = dbContext.fad_userFoods.Where(uf => uf.dateAdded == thisDate 
                                                         && uf.userID == thisGuid)
                                               .Sum(uf=> { decimal result;
                                                           decimal.TryParse(uf.quantityAmount,out result); 
                                                           return result;});
    

    【讨论】:

    • 我之前尝试过,但只是再次尝试并收到此错误消息:LINQ to Entities 无法识别方法'System.Decimal ToDecimal(System.Decimal)'方法,并且此方法不能翻译成商店表达式。
    • @stumcc:我已经更新了我的答案,请看一下。
    【解决方案4】:

    混淆源于 LINQ To Entities 中的 Sum 处理方式与 LINQ To Objects 中的处理方式略有不同。虽然从声明来看,在 let say decimal 上调用它看起来会返回 0,但当目标集为空时,SQL SUM 函数实际上返回 NULL,即使目标列不可为空。

    一旦你知道了,有两种方法可以解决它。

    假设我们有一个带有decimal 列的表,原始表达式是

    table.Sum(item => item.Column)
    

    第一种方法是使用Maarten answer中包含的模式对其进行转换:

    table.Select(item => item.Column).DefaultIfEmpty().Sum()
    

    第二种方法是在函数内部显式地将不可为空的类型转换为可空的类型,然后将null-coalescing operator应用于结果

    table.Sum(item => (decimal?)item.Column) ?? 0
    

    两种方式都起作用并产生相同的结果,因此请使用更适合您个人喜好的方式。

    为了完整起见,在您的案例中应用第二种方法基本上是将?? 0 移到Sum 调用之外:

    decimal foodCount = dbContext.fad_userFoods
        .Where(uf => uf.dateAdded == thisDate && uf.userID == thisGuid)
        .Sum(uf => (decimal?)uf.quantityAmount) ?? 0;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-13
      • 1970-01-01
      • 2012-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-29
      相关资源
      最近更新 更多