簡體   English   中英

如何使用linq添加子總計行和總計總計行

[英]How to add Sub total row and grand total row using linq

我想為每個BusinessTypeCode添加子總計行,為所有BusinessTypeCode添加總計。 如何在我的linq中添加這兩行,然后將每個businesstypecode的下面放進去。

我的當前代碼

var query = (from _transaction in _entities.Transactions
             join _cd in _entities.Organisations on _transaction.Refno equals _cd.Refno
             join _b in _entities.BusinessType on _transaction.BusinessTypeCode equals _b.BusinessTypeCode
             group new
             {
                 _trans = _transaction,
                 cd = _cd,
             }
             by new { _transaction.BusinessTypeCode,_transaction.Refno, _cd.BusinessName, _b.Description } into _group
             orderby _group.Key.BusinessTypeCode
             select new
             {
                 BusinessTypeCode = _group.Key.BusinessTypeCode,
                 BusType = _group.Key.BusinessTypeCode + " - " +_group.Key.Description,
                 BusName = _group.Key.BusinessName,
                 BusL = _group.Sum(x=>x._trans.BusL),
                 BusInterrest = _group.Sum(x => x._trans.BusInterrest),
                 BusAdmin = _group.Sum(x => x._trans.BusAdmin),
                 BusPenalty = _group.Sum(x => x._trans.BusPenalty),
                 TotalBusCollected =_group.Sum(x=>x._trans.TotalBusCollected)
             });
DataTable dt=new DataTable();
DataSet ds = new DataSet();
ds.Tables.Add(query.CopyToDataTable());
ds.Tables[0].TableName = "Table1";
var subtotal = query.GroupBy(x=>x.BusinessTypeCode ).Select(s=>new
{
    BusinessTypeCode =s.Key,
    BusLSub = s.Sum(x=>x.BusL),
    BusInterrestSub = s.Sum(x=>x.BusInterrest),
    BusAdminSub = s.Sum(x=>x.BusAdmin),
    BusPenaltySub = s.Sum(x=>x.BusPenalty),
    TotalBusCollectedSub = s.Sum(x=>x.TotalBusCollected),
});
foreach (var a in subtotal)
{
    dt = ds.Tables[0];
    dt.NewRow();
    dt.Rows.Add(a.BusLSub, a.BusInterrestSub, a.BusAdminSub, a.BusPenaltySub, a.TotalBusCollectedSub );
}
return ds;

電流輸出

BusType        |BusName   | BusL  |BusInterest|BusAdmin| BusPenalty|TotalBusCollected
1 - ACCOUNTING |HIGHVELD  |-23.91 | 0         |-22.84  | 0         |-46.75
1 - ACCOUNTING |BHP       |-50.81 |-79.21     |-76     |-20.02     |-226.04
2 - FOOD       |SAB       |-14.18 |-435.97    |-2.57   |-67.55     |-520.27
2 - FOOD       |DISTIL    |-43.05 |0          |-66,59  |0          |-109.64
3 - MINING     |ANGLOGOLD |-4.43  |0          |-72     |0          |-76.43
   -74.72      |-79.21    |-98.84 |-20.02     |-272.79
   -57.23      |-435.97   |-69.16 |-67.55     |-629.91
   -4.43       |0         |-72    |0          |-76.43

如何將其推入BusinessTypeCode = BusinessTypeCode的位置?

輸出需求像

   BusType     |BusName   | BusL  |BusInterest|BusAdmin| BusPenalty|TotalBusCollected
1 - ACCOUNTING |HIGHVELD  |-23.91 | 0         |-22.84  | 0         |-46.75
1 - ACCOUNTING |BHP       |-50.81 |-79.21     |-76     |-20.02     |-226.04
--------------------------+-------+-----------+--------+-----------+-----------------
Sub Total                 |-74.72 |-79.21     |-98.84  |-20.02     |-272.79
--------------------------+-------+-----------+--------+-----------+-----------------
 2 - FOOD      |SAB       |-14.18 |-435.97    |-2.57   |-67.55     |-520.27
 2 - FOOD      |DISTIL    |-43.05 |0          |-66,59  |0          |-109.64
--------------------------+-------+-----------+--------+-----------+-----------------
Sub Total                 |-57.23 |-435.97    |-69.16  |-67.55     |-629.91
--------------------------+-------+-----------+--------+-----------+-----------------
3 - MINING     |ANGLOGOLD |-4.43  |0          |-72     |0          |-76.43
--------------------------+-------+-----------+--------+-----------+-----------------
Sub Total                 |-4.43  |0          |-72     |0          |-76.43
--------------------------+-------+-----------+--------+-----------+-----------------
GRAND TOTAL               |-136.38|-515.38    |-240    |-87.57     |-979.13

看起來您需要的是某種交錯。 我沒有測試過,但是您想要的想法類似於以下內容(假設您有一個名為BusRow的類而不是匿名類型)。 我也自由選擇了使子行的類型與BusRow相同,但是當您這樣做時不必如此。

public static IEnumerable<BusRow> Interleave(List<BusRow> rowItems, List<BusRow> subTotalItems)
{
   for(int i = 0 ; i < rowItems.Count; ++i)
   {
     yield return rowItems[i];
     if(i > 0 && rowItems[i].BusinessTypeCode != rowItems[i-1].BusinessTypeCode)
     {
       yield return subTotalItems.Single(x => x.BusinessTypeCode == rowItems[i-1].BusinessTypeCode);
     }
   }
   yield return subTotalItems.Single(x => x.BusinessTypeCode == rowItems[rowItems.Count-1].BusinessTypeCode);
}

當然,您將更改原始查詢以返回BusRow,例如:

var subtotal = query.GroupBy(x=>x.BusinessTypeCode ).Select(s=>new BusRow
{
    BusinessTypeCode =s.Key,
    BusL = s.Sum(x=>x.BusL),
    BusInterrest = s.Sum(x=>x.BusInterrest),
    BusAdmin = s.Sum(x=>x.BusAdmin),
    BusPenalty = s.Sum(x=>x.BusPenalty),
    TotalBusCollected = s.Sum(x=>x.TotalBusCollected),
});

然后打電話

var interleaved = Interleave(query, subtotal);
foreach (var a in interleaved)
{
    dt = ds.Tables[0];
    dt.NewRow();
    if(String.isNullOrEmpty(a.BusName)//format your subtotal row as you like - add --rows before and after
       dt.Rows.Add(a.BusL, a.BusInterrest, a.BusAdmin, a.BusPenalty, a.TotalBusCollected ); 
   else
     dt.Rows.Add(a.BusinessTypeCode, a.BusName, a.BusL, a.BusInterrest, a.BusAdmin, a.BusPenalty, a.TotalBusCollected ); //normal row
}

由於我目前在移動設備上,因此我無法驗證這段代碼。

您可以執行以下操作:

foreach(var item in subtotal)
{
   var lastRecord = ds.Tables[0].Rows.LastOrDefault(r=>r["BusType"]==item.BusTypeCode);
   var lastIndex = ds.Tables[0].Rows.IndexOf(lastRecord);
   DataRow dr = ds.Tables[0].NewRow();
   dr["BusType"] = item.BusTypeCode;
   // etc.
   ds.Tables[0].Rows.InserAt(dr, lastIndex);
}

// insert the grand total row at the end

return ds;

這只是為了展示有關如何將當前DataSet輸出轉換為所需輸出的想法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM