【问题标题】:Sum in Linq to Sql not returning a value在 Linq to Sql 中求和不返回值
【发布时间】:2013-05-25 02:31:34
【问题描述】:

我正在寻找一个查询,以根据发票 ID 返回所有付款的总和 - 但是,如果没有记录任何付款,则下面的查询将返回 null。有什么方法可以返回 0 而不是 null 吗?我试过添加?? 0结尾,但是得到消息Operator ?? cannot be applied to operands of type decimal and int

AmountAllocated 是 Decimal 类型:

public decimal AmountAllocated { get; set; }

谢谢,马克

当没有找到支付行时,Sum 会返回 null:

 var invoiceVM = from i in db.Invoices
         where i.UserName==userName
         select new NewInvoiceViewModel
         {
           InvoiceId = i.InvoiceId,
           SumPayments = 
              db.PaymentInvoices.Where(pi => pi.InvoiceId == i.InvoiceId)
                                .Select(pi => pi.AmountAllocated).Sum()
                        };

以下导致Operator ?? cannot be applied to operands of type decimal and int错误:

  var invoiceVM = from i in db.Invoices
         where i.UserName==userName
         select new NewInvoiceViewModel
         {
           InvoiceId = i.InvoiceId,
           SumPayments = 
             db.PaymentInvoices.Where(pi => pi.InvoiceId == i.InvoiceId)
                                .Sum(pi => pi.AmountAllocated) ?? 0

                        };

如果已付款,则 AmountAllocated 正确返回这些付款的总和 - 如果没有找到付款行,则返回 null。

从下面的截图可以看到,第一条记录有付款,正确显示为10(十进制)-第二条记录没有付款,显示为null(十进制)。

【问题讨论】:

  • 要使用?? 运算符,您的操作数必须是Nullable<T>,例如decimal?int?
  • 我暂时删除了我的答案,因为感觉未知信息太多。 a) 您在哪里尝试使用??(在Sum 内部或外部)? b) AmountAllocated 的类型是什么? c) 当您说“下面的查询返回 null”时,您的意思是 SumPayments 对于某些行为 null,还是没有结果? d) AmountAllocated 是否为空?
  • 嗨 - 我已经更新了我的问题,以更清楚地显示我在寻找什么。谢谢,马克
  • Sum() 返回一个不可为空的int(或decimal),因此它将返回一个0 而不是null
  • 嗨 - 它没有 - 我已经更新了我的问题以显示屏幕截图,它返回第一条记录的值,第二条记录显示为空。谢谢,马克

标签: c# asp.net-mvc linq linq-to-sql


【解决方案1】:

您可以尝试测试是否有要返回的行。

{
       InvoiceId = i.InvoiceId,
       SumPayments = 
          db.PaymentInvoices.Any(pi => pi.InvoiceId == i.InvoiceId)
          ? db.PaymentInvoices.Where(pi => pi.InvoiceId == i.InvoiceId)
                              .Select(pi => pi.AmountAllocated).Sum()
          : 0
};

另一种选择是使用 SumPayments.GetValueOrDefault(),它将返回值或 0。

【讨论】:

    【解决方案2】:

    我相信这是因为在 SQL 中所有数据类型都可以为空,但在 C# 中却不是这样。尝试使用.ToList() 强制枚举您的付款发票,然后再对它们进行汇总。

    SumPayments = db.PaymentInvoices.Where(pi => pi.InvoiceId == i.InvoiceId)
                                    .Select(pi => pi.AmountAllocated)
                                    .ToList()
                                    .Sum()
    

    更新:尝试将查询编写为从 Invoices 到 PaymentInvoices 的联接,并改为按 InvoiceId 分组。我认为您遇到的问题是因为您试图将汇总总和作为子查询执行。

    【讨论】:

    • 感谢您的建议 - 我完全按照上面添加了您的代码,但出现错误(在运行时,而不是编译时):{“LINQ to Entities 无法识别方法 'System.Collections.Generic .List1[System.Decimal] ToList[Decimal](System.Collections.Generic.IEnumerable1[System.Decimal])' 方法,并且该方法不能转换为存储表达式。"} System.Exception {System.NotSupportedException}
    • 哦,我明白了。这是因为 Sum 是一个子选择。也许如果您重新编写查询以将 Invoice 表加入 PaymentInvoices 并按 InvoiceId 而不是子查询分组。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-30
    • 2012-03-05
    相关资源
    最近更新 更多