C# 在多个数据行中创建列集合的干净方法
我有一系列DataRow对象,每个对象都有一组不同的字段。我要做的是创建一个新的DataRow对象,其中包含某些十进制字段的总和。现在,我的代码如下所示:C# 在多个数据行中创建列集合的干净方法,c#,dataset,C#,Dataset,我有一系列DataRow对象,每个对象都有一组不同的字段。我要做的是创建一个新的DataRow对象,其中包含某些十进制字段的总和。现在,我的代码如下所示: DataRow tally = myTable.NewRow(); foreach (DataRow row in myTable.Rows) { if (row["SomeField"] != DBNull.Value) tally["SomeField"] = (tally["SomeField"] is DBNull
DataRow tally = myTable.NewRow();
foreach (DataRow row in myTable.Rows)
{
if (row["SomeField"] != DBNull.Value)
tally["SomeField"] = (tally["SomeField"] is DBNull ? 0 : (Decimal)tally["SomeField"]) + (Decimal)row["SomeField"];
// ...
}
我需要对大约20个其他字段执行同样的操作,但我认为由于所有类型转换和空检查,代码非常混乱。是否有办法重构此代码,使其更具可读性
注意:我只想对某些列进行汇总,否则我可能只会在DataRow中的列中循环,而不是重复上面的代码20次。您可以使用Linq对数据集进行汇总:
如果您想使用LINQ,这里有一个简单的示例
DataTable table = new DataTable();
table.Columns.Add("Desc", typeof(string));
table.Columns.Add("Qty", typeof(decimal));
table.Columns.Add("Price", typeof(decimal));
table.Rows.Add(new object[] { "Product", 1, 2 });
table.Rows.Add(new object[] { "Product", 2, 10 });
table.Rows.Add(new object[] { "Product", 3, null });
var totalQty = table.AsEnumerable().GroupBy(l => l.Field<string>("Desc"))
.Select(r =>
new { Desc = r.Key,
TotalQty = r.Sum(w => w.Field<decimal?>("Qty")),
TotalPrice = r.Sum(w => w.Field<decimal?>("Price")),
});
您可以将计算代码移动到新方法中:
private void Tally(DataRow tally, DataRow row, int index)
{
if (row[index] != DBNull.Value)
{
tally[index] = (tally[index] == DBNull.Value ? 0 : (decimal)tally[index]) + (decimal)row[index];
}
}
并对要计数的列使用索引数组:
DataRow tally = myTable.NewRow();
int[] indexes = new int[] { 0, 2 };
foreach(DataRow row in myTable.Rows)
{
foreach(int index in indexes)
{
Tally(tally, row, index);
}
}
您还可以使用DataTable类的Compute方法:。我有点想避免这种情况,因为我已经在数据集中循环以写出每一行,LINQ表达式将导致我再次遍历数据集,然后获得总数。是的,我实际上正在考虑这种方法(只使用字符串数组,因为我讨厌在列索引中进行硬编码)…这确实让东西不那么难看。这也是我能找到的最干净的方法。我循环使用字符串数组,并称我的“凌乱”每次迭代编写一次代码。我决定不过度考虑使用LINQ,因为我想自己控制循环,而不是执行大量O(n)LINQ调用。
DataRow tally = myTable.NewRow();
int[] indexes = new int[] { 0, 2 };
foreach(DataRow row in myTable.Rows)
{
foreach(int index in indexes)
{
Tally(tally, row, index);
}
}