使用 C# 在数据 table 中递归添加值
Add values recursively in data table using c#
我有这样的数据table:
===================================================================
ID | Parent ID | Parent Node | Name | Values
===================================================================
1 | 0 | Primary Node | Master1 | 0
2 | 0 | Primary Node | Master2 | 0
3 | 1 | Master1 | Group1 | 0
4 | 2 | Master2 | Group2 | 0
5 | 3 | Group1 | Child1 | 10
6 | 4 | Group2 | Child2 | 20
7 | 4 | Group2 | Child3 | 30
我需要这样的输出:
===================================================================
ID | Parent ID | Parent Node | Name | Values
===================================================================
1 | 0 | Primary Node | Master1 | 10
2 | 0 | Primary Node | Master2 | 50
3 | 1 | Master1 | Group1 | 10
4 | 2 | Master2 | Group2 | 50
5 | 3 | Group1 | Child1 | 10
6 | 4 | Group2 | Child2 | 20
7 | 4 | Group2 | Child3 | 30
实际上 table 的顺序不正确:
我尝试了下面的递归方法来排列,但不知道如何根据父组得到累加值
public DataTable RecursiveTreeTable(DataTable table, String parentNode, String dataColumn)
{
ParentNodeColumnName = parentNode;
DataColumnName = dataColumn;
TblTree = table.Copy();
TblTree.Clear();
if (table.Rows.Count > 0)
{
foreach (DataRow dr in table.Rows)
{
if (Convert.ToInt64(dr["ParentNodeId"]) == 0)
{
TblTree.ImportRow(dr);
FillNodeChildren(Convert.ToInt64(dr["Id"]), table);
}
}
}
return TblTree;
}
public void FillNodeChildren(Int64 parentID, DataTable table)
{
foreach (DataRow dr in table.Rows)
{
if (Convert.ToInt64(dr["ParentNodeId"]) != 0)
{
if (object.Equals(dr["ParentNodeId"].ToString(), parentID.ToString()))
{
TblTree.ImportRow(dr);
FillNodeChildren(int.Parse(dr["Id"].ToString()), table);
}
}
}
}
我做了一个例子,但这是用 notepad++ 写的,所以没有错误检查等。所以你必须修正一些小错别字等。
我会创建一个方法,returns 所有 children 的总和。
public DataTable RecursiveTreeTable(DataTable table, String parentNode, String dataColumn)
{
ParentNodeColumnName = parentNode;
DataColumnName = dataColumn;
TblTree = table.Copy();
TblTree.Clear();
if (table.Rows.Count > 0)
{
foreach (DataRow dr in table.Rows)
{
var desRow = TblTree.NewRow();
desRow.ItemArray = dr.ItemArray.Clone() as object[];
desRow["Values"] = SumOfValuesForAllChildren(dr, table);
}
}
return TblTree;
}
public decimal SumOfValuesForAllChildren(DataRow parentRow, DataTable table)
{
var parentID = Convert.ToInt64(parentRow["Id"]);
// start with the parent value.
var result = Convert.ToDecimal(parentRow["Values"]);
foreach (DataRow dr in table.Rows)
{
var childParentId = Convert.ToInt64(dr["ParentNodeId"]);
if (childParentId == parentID)
// add the child values
result += SumOfValuesForAllChildren(dr, table);
}
return result;
}
此方法将一遍又一遍地扫描所有 children。这不是最佳解决方案,但可能有助于解决您的 'problem'.
别忘了,这会在循环参考上给出一个计算器。 (parent 的 child 为 parent)
我已经写了我自己的逻辑,它运行良好:)
public DataTable AddingRecursive(DataTable table)
{
for (int i = table.Rows.Count - 1; i >= 0; i--)
{
if (Convert.ToInt64(table.Rows[i]["Parent ID"]) != 0)
{
Int64 parentNode = Convert.ToInt64(table.Rows[i]["Parent ID"]);
Decimal value = Convert.ToDecimal(table.Rows[i]["Values"]);
foreach (DataRow row in table.Rows)
{
if (parentNode == Convert.ToInt64(row["ID"]))
{
row["Values"] = Convert.ToDecimal(row["Values"]) + value;
}
}
}
}
return table;
}
我有这样的数据table:
===================================================================
ID | Parent ID | Parent Node | Name | Values
===================================================================
1 | 0 | Primary Node | Master1 | 0
2 | 0 | Primary Node | Master2 | 0
3 | 1 | Master1 | Group1 | 0
4 | 2 | Master2 | Group2 | 0
5 | 3 | Group1 | Child1 | 10
6 | 4 | Group2 | Child2 | 20
7 | 4 | Group2 | Child3 | 30
我需要这样的输出:
===================================================================
ID | Parent ID | Parent Node | Name | Values
===================================================================
1 | 0 | Primary Node | Master1 | 10
2 | 0 | Primary Node | Master2 | 50
3 | 1 | Master1 | Group1 | 10
4 | 2 | Master2 | Group2 | 50
5 | 3 | Group1 | Child1 | 10
6 | 4 | Group2 | Child2 | 20
7 | 4 | Group2 | Child3 | 30
实际上 table 的顺序不正确:
我尝试了下面的递归方法来排列,但不知道如何根据父组得到累加值
public DataTable RecursiveTreeTable(DataTable table, String parentNode, String dataColumn)
{
ParentNodeColumnName = parentNode;
DataColumnName = dataColumn;
TblTree = table.Copy();
TblTree.Clear();
if (table.Rows.Count > 0)
{
foreach (DataRow dr in table.Rows)
{
if (Convert.ToInt64(dr["ParentNodeId"]) == 0)
{
TblTree.ImportRow(dr);
FillNodeChildren(Convert.ToInt64(dr["Id"]), table);
}
}
}
return TblTree;
}
public void FillNodeChildren(Int64 parentID, DataTable table)
{
foreach (DataRow dr in table.Rows)
{
if (Convert.ToInt64(dr["ParentNodeId"]) != 0)
{
if (object.Equals(dr["ParentNodeId"].ToString(), parentID.ToString()))
{
TblTree.ImportRow(dr);
FillNodeChildren(int.Parse(dr["Id"].ToString()), table);
}
}
}
}
我做了一个例子,但这是用 notepad++ 写的,所以没有错误检查等。所以你必须修正一些小错别字等。
我会创建一个方法,returns 所有 children 的总和。
public DataTable RecursiveTreeTable(DataTable table, String parentNode, String dataColumn)
{
ParentNodeColumnName = parentNode;
DataColumnName = dataColumn;
TblTree = table.Copy();
TblTree.Clear();
if (table.Rows.Count > 0)
{
foreach (DataRow dr in table.Rows)
{
var desRow = TblTree.NewRow();
desRow.ItemArray = dr.ItemArray.Clone() as object[];
desRow["Values"] = SumOfValuesForAllChildren(dr, table);
}
}
return TblTree;
}
public decimal SumOfValuesForAllChildren(DataRow parentRow, DataTable table)
{
var parentID = Convert.ToInt64(parentRow["Id"]);
// start with the parent value.
var result = Convert.ToDecimal(parentRow["Values"]);
foreach (DataRow dr in table.Rows)
{
var childParentId = Convert.ToInt64(dr["ParentNodeId"]);
if (childParentId == parentID)
// add the child values
result += SumOfValuesForAllChildren(dr, table);
}
return result;
}
此方法将一遍又一遍地扫描所有 children。这不是最佳解决方案,但可能有助于解决您的 'problem'.
别忘了,这会在循环参考上给出一个计算器。 (parent 的 child 为 parent)
我已经写了我自己的逻辑,它运行良好:)
public DataTable AddingRecursive(DataTable table)
{
for (int i = table.Rows.Count - 1; i >= 0; i--)
{
if (Convert.ToInt64(table.Rows[i]["Parent ID"]) != 0)
{
Int64 parentNode = Convert.ToInt64(table.Rows[i]["Parent ID"]);
Decimal value = Convert.ToDecimal(table.Rows[i]["Values"]);
foreach (DataRow row in table.Rows)
{
if (parentNode == Convert.ToInt64(row["ID"]))
{
row["Values"] = Convert.ToDecimal(row["Values"]) + value;
}
}
}
}
return table;
}