IQueryable总和两个唯一ID匹配的数量C#

时间:2017-01-28 18:23:50

标签: c# mysql linq

我有一张桌子,我正在查询。每笔付款都有一个总数和一个代表费用的负数。目前,我的查询在没有负数的情况下提取所需的查询。

随着我最近得到的改变,我需要而不是只选择我需要的正数来将正数和负数加在一起,其中batchId在单个表中匹配。

我一直在研究它几个小时以及我尝试的所有内容我最终总结了查询中的所有内容,而不仅仅是批次ID匹配的负数和正数。

请帮忙。下面是我的查询,它是我想要总和的金额列。

左边的示例数据,我想要的是右边的

batchId Amount      batchId Amount
1       2.23        1       1.00
1      -1.23        2       3.00
2       5.43m       3       4.00
2      -2.43
3       6.60
3      -3.60

IQueryable<BatchPayment> query = _db
                .BatchPayments
                .Where(
                    bp => ValidBatchStatuesIds.Contains(bp.Batch.BatchStatusId)
                        && (!OnlineBatchTypes.Contains(bp.Batch.BatchTypeId)
                            || (OnlineBatchTypes.Contains(bp.Batch.BatchTypeId) && bp.Amount > 0.00m))
                );

2 个答案:

答案 0 :(得分:0)

如果我理解你,你需要做两件事:

  1. 获取符合该规则的所有batchIds
  2. 获取此类batchIds的所有(无论是否符合)付款的总和。
  3. 可以这样做:

    var query = _db
        .BatchPayments
        .Where(
            bp => ValidBatchStatuesIds.Contains(bp.Batch.BatchStatusId)
                && (!OnlineBatchTypes.Contains(bp.Batch.BatchTypeId)
                    || (OnlineBatchTypes.Contains(bp.Batch.BatchTypeId) && bp.Amount > 0.00m))
        )
        // Get batchIds that have payments conforming to the rule.
        .Select(bp =>
            bp.batchId)
        // Remove duplicate batchIds
        .Distinct()
        // Select each and every BatchPayment with previously found batchIds
        .SelectMany(batchId =>
            _db
                .BatchPayments
                .Where(bp =>
                    bp.batchId == batchId))
        // Group found batchPayments
        .GroupBy(bp =>
            bp.batchId)
        // Get sum for each batchId
        .Select(gr =>
            new
            {
                batchId = gr.Key,
                Amount = gr.Sum(i => i.Amount)
            });
    

    嗯,虽然理论上.SelectMany(batchId => _db.BatchPayments可能不完全有用,所以你用Join做得更好(而且它可能更加惯用):

    var query = _db
        .BatchPayments
        // Join to the self...
        .Join(
            // ...where all improper batchIds are already filtered out
            _db
                .BatchPayments
                .Where(
                    bp => ValidBatchStatuesIds.Contains(bp.Batch.BatchStatusId)
                        && (!OnlineBatchTypes.Contains(bp.Batch.BatchTypeId)
                            || (OnlineBatchTypes.Contains(bp.Batch.BatchTypeId) && bp.Amount > 0.00m))),
            sc => sc.batchId,
            soc => soc.batchId,
            (sc, soc) => sc)        
        // Group found batchPayments
        .GroupBy(bp =>
            bp.batchId)
        // Get sum for each batchId
        .Select(gr =>
            new
            {
                batchId = gr.Key,
                Amount = gr.Sum(i => i.Amount)
            });
    

答案 1 :(得分:0)

试一试(为了正确验证我正在跳过不相关的条件):

var result = _db.BatchPayments
                 .GroupBy(p=> p.BatchId)
                 .Select(p=> new { BatchId = p.Key, Amount = p.Sum(q=> q.Amount)})
                 .ToList();
foreach (var batch in result)
{
    Console.WriteLine("BatchId = {0} Amount={1}", batch.BatchId, batch.Amount);
}