简化LINQ-使用两个不同的where子句的Col的总和两次

时间:2019-07-05 05:10:40

标签: c# linq

下面的代码段需要两次往返数据库,因为where子句不同。

public string OutStanding(string PC)
{
    var d = _context.MyTable.Where(w => w.debit == PC).Sum(s => s.amount);
    var c = _context.MyTable.Where(w => w.credit == PC).Sum(s => s.amount);
    return (d - c).ToString();
}

可以简化为一次往返DB吗?

4 个答案:

答案 0 :(得分:3)

您可以应用查询并稍后提取

public string OutStanding(string PC) {
    var myTable =_context.MyTable.Where(w => w.debit == PC || w.credit == PC).ToList();
    var d = myTable.Where(w => w.debit == PC).Sum(s => s.amount);
    var c = myTable.Where(w => w.credit == PC).Sum(s => s.amount);
    return (d - c).ToString(); 
}

答案 1 :(得分:3)

您可以尝试以下方法:

return _context.MyTable.
          Where(w => w.debit == PC || w.credit == PC).
          Sum(s => w.credit == PC ? -s.amount : s.amount).ToString();

但是检查生成的sql。根据EF和使用的数据库的版本,可能会在客户端上对此进行评估。

答案 2 :(得分:2)

我建议在单个查询中获得最终的差异。

public string OutStanding(string PC)
{
    return _context.MyTable.Take(1).Select(x =>
        _context.MyTable.Where(w => w.debit == PC).Sum(s => s.amount) -
        _context.MyTable.Where(w => w.credit == PC).Sum(s => -s.amount)
    );
}

想法是获取如下所示的SQL语句:

-- replace PC with the equivalent numeric value
SELECT (
    SELECT SUM(Amount) AS subtotal FROM MyTable WHERE debit = PC
) - (
    SELECT SUM(Amount) FROM MyTable WHERE credit = PC
)

尽管实际上看起来更像是这样(在SQL Server上):

-- replace PC with the equivalent numeric value
SELECT TOP 1 (
    SELECT SUM(Amount) AS subtotal FROM MyTable WHERE debit = PC
) - (
    SELECT SUM(Amount) FROM MyTable WHERE credit = PC
) AS Difference
FROM MyTable

答案 3 :(得分:0)

是的,您可以将其简化为一次往返数据库的操作,例如

public string OutStanding(string PC)
{
    var rawData = _context.MyTable.Where(w => w.debit == PC || w.credit == PC).ToList();
                                                          //^^ using OR operator 
    var d = rawData.Where(w => w.debit == PC).Sum(s => s.amount);
    var c = rawData.Where(w => w.credit== PC).Sum(s => s.amount);
    return (d - c).ToString();
}