我已经在其他地方发布了此内容,但我对要求的理解对于帮助我的版主 @ShaiCohen 来说是不正确的,他建议我重新发布它。
我需要编辑输入到 DataTable
的数据,该数据可以具有不同的列和行,但前两列是不变的。数据如下所示(行开头的数字不是数据的一部分):
Repair Repair
Code Code Entries 6/1/2012 7/1/2012 8/1/2012 9/1/2012
------ -------------------- -------- -------- -------- --------
1. 00000A Critical Down Time 1
2. 00000A Critical Outage 1
3. 00000A Total Repair Time 65
4. 00000B Critical Down Time 6
5. 00000B Total Repair Time 90
6. 00000C Critical Down Time 1 5
7. 00000C Critical Outage 1 5
8. 00000C Total Repair Time 30 240
9. 00000D Critical Down Time 2
10. 00000E Critical Down Time 1
11. 00000G Critical Down Time 1
12. 00000M Critical Down Time 1 3
13. 00000M Critical Outage 1 3
14. 00000M Total Repair Time 60 180
请注意,第 1-3 行、第 6-8 行具有相同的修复代码类别,因此被视为一组。另一方面,第 10-12 行只有“关键停机时间”子类别,而其余的则具有三者的组合。
要求是在不存在的位置插入“修复代码条目”子类别。它们不存在的原因是数据库中没有数据,但客户端希望看到显示的缺失措辞,即使没有相应的数据,并插入一个空行来分隔各组,如下所示:
Repair Repair
Code Code Entries 6/1/2012 7/1/2012 8/1/2012 9/1/2012
------ -------------------- -------- -------- -------- --------
1. 00000A Critical Down Time 1
2. 00000A Critical Outage 1
3. 00000A Total Repair Time 65
4. 00000B Critical Down Time 6
00000B Critical Outage
5. 00000B Total Repair Time 90
6. 00000C Critical Down Time 1 5
7. 00000C Critical Outage 1 5
8. 00000C Total Repair Time 30 240
9. 00000D Critical Down Time 2
00000D Critical Outage
00000D Total Repair Time
但是,当前的代码假设数据始终包含三个子类别的分组,因此当不是时,前一行的子类别将覆盖当前行中的子类别:
8. 00000C Total Repair Time 30 240
9. 00000D Total Repair Time (should be Critical Down Time) 2
00000D Critical Outage
在下面的代码中,CheckSubCategoryRequirements
方法内的计数器 subCategoryOccurences
在处理新行时不会重置为零。
public void PrepareDataTable(DataTable dtResults)
{
if (dtResults == null || dtResults.Rows.Count == 0)
return;
//initialize category
categoryPrevious = dtResults.Rows[0]["Category"].ToString();
do
{
//get the current category
categoryCurrent = dtResults.Rows[rowCount]["Category"].ToString();
//check if this is a new category. this is where all the work is done
if (categoryCurrent != categoryPrevious)
{
//check if we have fulfilled the requirement for number of subcategories
CheckSubCategoryRequirements(dtResults);
//at this point we have fulfilled the requirement for number of subcategories
//add blank (separator) row
dtResults.Rows.InsertAt(dtResults.NewRow(), rowCount);
rowCount++;
//reset the number of subcategories
subCategoryOccurences = 0;
categoryPrevious = categoryCurrent;
}
else
{
rowCount++;
categoryOccurences++;
}
} while (rowCount < dtResults.Rows.Count);
//check sub category requirements for the last category
CheckSubCategoryRequirements(dtResults);
}
private void CheckSubCategoryRequirements(DataTable dtResults)
{
if (subCategoryOccurences< subCategories.Length)
{
//we need to add rows for the missing subcategories
while (subCategoryOccurences< subCategories.Length)
{
//create a new row and populate category and subcategory info
rowFiller = dtResults.NewRow();
rowFiller["Category"] = categoryPrevious;
rowFiller["SubCategory"] = subCategories[subCategoryOccurences];
//insert the new row into the current location of table
dtResults.Rows.InsertAt(rowFiller, rowCount);
subCategoryOccurences++;
rowCount++;
}
}
}
我尝试在方法调用之前移动计数器,但这导致了不期望的结果,所以我不确定从这里该去哪里。我将不胜感激建设性的意见。谢谢。 R。
最佳答案
对于这些要求,我采取了与以前不同的方法。有了这些新的要求,我们将不得不“向后”插入以前丢失的子类别。
此方法创建一个新表,该表为原始表中存在的每个类别填充正确数量的子类别。创建新行后,我们会检查旧表,看看是否有任何数据需要复制到新表(即:“6/1/2012”和“7/1/2012”来自您的示例)。
试试这个代码:
public DataTable PrepareDataTable(DataTable dtResults)
{
string[] subCategories = new string[3] {"Critical Down Time", "Critical Outage", "Total Repair Time"};
//make a copy of the original table
DataTable dtOutput = dtResults.Clone();
DataRow drOutput = null;
DataRow[] drResults = null;
//retrieve the list of Categories
var categories = dtResults.AsEnumerable().Select(r => r["Category"]).Distinct().ToList();
//populate the new table with the appropriate rows (combinations of categories/subcategories)
foreach (string category in categories)
{
for (int i = 0; i < subCategories.Length ; i++)
{
//create the new row in the new table
drOutput = dtOutput.NewRow();
drOutput["Category"] = category;
drOutput["SubCategory"] = subCategories[i];
//here is where you will check to see if a row with the same category and subcategory exists in dtResults. if it does, then copy over the values for each column
drResults = dtResults.Select(String.Format("Category = '{0}' AND SubCategory = '{1}'", category, subCategories[i]));
if(drResults.Length > 0)
{
foreach(DataColumn column in dtResults.Columns)
{
drOutput[column.ColumnName] = drResults[0][column.ColumnName];
}
}
dtOutput.Rows.Add(drOutput);
}
//add filler/spacer row
drOutput = dtOutput.NewRow();
dtOutput.Rows.Add(drOutput);
}
return dtOutput;
}
这是“测试工具”:
public void RunTest()
{
DataTable dtResults = new DataTable();
dtResults.Columns.Add("Category");
dtResults.Columns.Add("SubCategory");
dtResults.Columns.Add("Data");
dtResults.Rows.Add("00000A", "Critical Down Time", "1");
dtResults.Rows.Add("00000A", "Critical Outage", "1");
dtResults.Rows.Add("00000A", "Total Repair Time", "1");
dtResults.Rows.Add("00000B", "Critical Down Time", "1");
dtResults.Rows.Add("00000B", "Total Repair Time", "1");
dtResults.Rows.Add("00000C", "Critical Down Time", "1");
dtResults.Rows.Add("00000C", "Critical Outage", "1");
dtResults.Rows.Add("00000C", "Total Repair Time", "1");
dtResults.Rows.Add("00000D", "Critical Down Time", "1");
dtResults.Rows.Add("00000E", "Critical Down Time", "1");
dtResults.Rows.Add("00000G", "Critical Down Time", "1");
dtResults.Rows.Add("00000M", "Critical Down Time", "1");
dtResults.Rows.Add("00000M", "Critical Outage", "1");
dtResults.Rows.Add("00000M", "Total Repair Time", "1");
DataTable dtOutput = PrepareDataTable(dtResults);
}
关于c# - 在数据表中追加记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15277849/