如何获得子查询的多个总和

时间:2016-07-22 21:18:43

标签: entity-framework linq linq-to-sql

我使用Linqpad测试我的EF查询,我似乎无法得到我的最终结果,包括一些额外的列,表示基于不同条件的字段总和

StorePaymentInvoices表包含一个FK到CustomerStatementBatchPayments。所以如果StorePaymentInvoices中有相应的值,我需要将CustomerStatementBatchPayment.net字段相加

获得总和变得非常混乱。有什么建议? 有时在一个陈述中很难做到,最终会在多个步骤中更容易完成。

var retval = (
            from a in CustomerStatementBatches 
            join b in CustomerStatementBatchPayments on a.ID equals b.CustomerStatementBatchID into grp1
            from c in grp1              
            where a.CustomerStatementID == StatementId 
            group c by c.CustomerStatementBatchID into grp2
            from e in grp2              
            select new { 
                StatementId = e.CustomerStatementBatch.CustomerStatementID,
                BatchId = e.CustomerStatementBatchID,
                Applied =  CustomerStatementBatchPayments.Where(csbp => !StorePaymentInvoices.Select (pi => pi.CustomerStatementBatchPaymentID ).ToList().Contains(e.ID)).Sum (csbp => csbp.Net )
            }
            ).ToList();
retval.Dump();      

[更新1]
这就是我为了获得"条件"总和值,我似乎得到正确的数字。它生成的结果SQL有点难看,但在< 1秒。

    var retval1 = (
            from a in CustomerStatementBatches 
            join b in CustomerStatementBatchPayments on a.ID equals b.CustomerStatementBatchID into grp1
            from c in grp1              
            where a.CustomerStatementID == StatementId 
            group c by new { a.CustomerStatementID, c.CustomerStatementBatchID} into grp2
            from e in grp2.Distinct()
            select new { 
                StatementId = e.CustomerStatementBatch.CustomerStatementID,
                BatchId = e.CustomerStatementBatchID
            }
            ).ToList()
            .Distinct()
            .Select(a => new 
            {
                StatementId = a.StatementId, 
                BatchId = a.BatchId,
                AppliedTotal = (from b in CustomerStatementBatchPayments.Where(r => r.CustomerStatementBatchID == a.BatchId) 
                                join c in StorePaymentInvoices on b.ID equals c.CustomerStatementBatchPaymentID                                                                     
                                group b by b.CustomerStatementBatchID into g1 
                                from d in g1
                                select new{ Total = (decimal?)d.Net}).DefaultIfEmpty().Sum (at => (decimal?)at.Total ) ?? 0.0m,
                Unappliedtotal = (from b in CustomerStatementBatchPayments.Where(r => r.CustomerStatementBatchID == a.BatchId) 
                                .Where(s => !StorePaymentInvoices.Any (pi => pi.CustomerStatementBatchPaymentID == s.ID ) )
                                select new{ Total = (decimal?)b.Net}).DefaultIfEmpty().Sum (at => (decimal?)at.Total ) ?? 0.0m                                  
            })
            .ToList();

1 个答案:

答案 0 :(得分:0)

试试这个

from a in db.CustomerStatementBatches 
join b in db.CustomerStatementBatchPayments
            //.Where(i => ...)
            .GroupBy(i => i.CustomerStatementBatchesId)
            .Select(i => new { 
                                CustomerStatementBatchesId = i.Key,
                                SumOfPayments = i.Sum(t => t.Net)
                             }
                    ) 
           into tmp from b in tmp.DefaultIfEmpty() 
       on a.CustomerStatementBatchesId equals b.CustomerStatementBatchesId 
select new
{
    StatementId = a.CustomerStatementId,
    BatchId = a.CustomerStatementBatchId,
    Applied =  ((b == null) ? 0 : b.SumOfPayments)
}