[英]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.