C#实现拆分DataTable中分号拼接列生成新DataTable
解决DataTable多列分号分隔元素拆分问题
我来帮你搞定这个DataTable拆分的需求!你的核心目标是把logistique、amount等列中用分号拼接的元素拆分成单独行,同时保留原行其他列的数值,对吧?你当前的代码问题在于条件判断过于复杂混乱,不仅逻辑有误,还会重复生成不必要的行。下面是修正后的方案:
核心思路
- 克隆原DataTable的结构,确保新表和原表列完全一致
- 遍历原表每一行,提取不需要拆分的固定列值(
produit、test1、test3) - 将需要拆分的列按分号拆分为字符串数组,同时处理可能的空值情况
- 计算所有拆分数组的最大长度,以此作为循环次数,保证每个元素都能生成对应行
- 针对每个索引位置,为拆分列赋值:若索引在数组范围内则取对应元素,否则赋值为
null(或空字符串,可按需调整) - 将固定列值和处理后的拆分列值一起添加到新表中
修正后的完整代码
using System; using System.Data; using System.Linq; namespace ConsoleApplication9 { class Program { static void Main(string[] args) { // 初始化原DataTable DataTable dt1 = new DataTable(); dt1.Columns.Add("produit", typeof(string)); dt1.Columns.Add("test1", typeof(int)); dt1.Columns.Add("test3", typeof(int)); dt1.Columns.Add("logistique", typeof(string)); dt1.Columns.Add("amount", typeof(string)); dt1.Columns.Add("testAjout", typeof(string)); dt1.Columns.Add("testAjout1", typeof(string)); dt1.Rows.Add(new object[] { "P1", 1, 3, "t3;t1;t2", "t4;t5;t6;tr", "T34;T25", "Rahima;T33;T55;T66" }); dt1.Rows.Add(new object[] { "P2", 1, 4, "t9;t10;t55", "t2;t1;t3", "t34;t45", "Nadji" }); // 克隆原表结构,创建新表 DataTable dt2 = dt1.Clone(); foreach (DataRow row in dt1.AsEnumerable()) { // 提取固定列的值 string produit = row.Field<string>("produit"); int test1 = row.Field<int>("test1"); int test3 = row.Field<int>("test3"); // 拆分需要处理的列,空值时返回空数组避免报错 string[] splitLogistique = row.Field<string>("logistique")?.Split(';') ?? Array.Empty<string>(); string[] splitAmount = row.Field<string>("amount")?.Split(';') ?? Array.Empty<string>(); string[] splitAjout = row.Field<string>("testAjout")?.Split(';') ?? Array.Empty<string>(); string[] splitAjout1 = row.Field<string>("testAjout1")?.Split(';') ?? Array.Empty<string>(); // 计算所有拆分数组的最大长度,确保每个元素都能生成对应行 int maxLength = new[] { splitLogistique.Length, splitAmount.Length, splitAjout.Length, splitAjout1.Length }.Max(); for (int i = 0; i < maxLength; i++) { // 为每个拆分列赋值,索引超出范围则设为null string logistiqueVal = i < splitLogistique.Length ? splitLogistique[i] : null; string amountVal = i < splitAmount.Length ? splitAmount[i] : null; string ajoutVal = i < splitAjout.Length ? splitAjout[i] : null; string ajout1Val = i < splitAjout1.Length ? splitAjout1[i] : null; // 添加新行到新表 dt2.Rows.Add(produit, test1, test3, logistiqueVal, amountVal, ajoutVal, ajout1Val); } } // 输出结果验证 foreach (DataRow row in dt2.Rows) { foreach (DataColumn col in dt2.Columns) { Console.Write($"\t{row[col] ?? "(空)"}"); } Console.WriteLine(); } } } }
原代码的问题说明
你之前的代码中,多个if条件会同时触发(比如当索引超出某一个数组长度时,多个条件判断都会成立),导致同一索引位置生成多行重复数据,完全不符合“每个元素单独占一行”的需求。修正后的代码通过统一的循环和索引判断,逻辑清晰且能准确生成所需的行。
内容的提问来源于stack exchange,提问作者lili1986
相关产品推荐
相关产品推荐

