C#动态列DataTable关联查询:合并两表所有列至单行
我明白你的问题了——你现在用Linq关联两个DataTable后,结果里每个匹配项是两个DataRow的包装对象,导致最终输出的DataTable把它们拆成了不符合预期的结构,而你需要把两个表的字段合并到同一行里。因为dtFormData的列是动态的,所以不能硬编码列名来拼接,得用通用的方式处理。
下面是完整的解决方案,分两步走:
1. 先构建结果DataTable的列结构
首先要把两个表的所有列都加到结果表里,还要处理可能的列名重复问题(比如两个表都有"Id"列),可以给第二个表的列加个前缀区分:
DataTable dtRtn = new DataTable(); // 添加dtFormData的所有列(动态列也能适配) foreach (DataColumn col in dtFormData.Columns) { dtRtn.Columns.Add(col.ColumnName, col.DataType); } // 添加dtResponderDetails的列,处理重复列名 foreach (DataColumn col in dtResponderDetails.Columns) { string targetColName = col.ColumnName; // 如果列名已存在,添加前缀避免冲突 if (dtRtn.Columns.Contains(targetColName)) { targetColName = $"Responder_{targetColName}"; } dtRtn.Columns.Add(targetColName, col.DataType); }
2. 执行关联查询并填充合并后的行
接下来执行你的关联逻辑,然后把每个匹配的两个DataRow的字段值依次填充到结果表的新行里:
// 执行关联查询 var result = from d1 in dtFormData.AsEnumerable() join d2 in dtResponderDetails.AsEnumerable() on d1.Field<string>("ResponderId") equals d2.Field<string>("EmployeeId") select new { d1, d2 }; // 遍历查询结果,填充合并行 foreach (var item in result) { DataRow newRow = dtRtn.NewRow(); // 填充dtFormData的所有字段 foreach (DataColumn col in dtFormData.Columns) { newRow[col.ColumnName] = item.d1[col]; } // 填充dtResponderDetails的所有字段 foreach (DataColumn col in dtResponderDetails.Columns) { string targetColName = col.ColumnName; if (dtRtn.Columns.Contains(targetColName)) { targetColName = $"Responder_{targetColName}"; } newRow[targetColName] = item.d2[col]; } dtRtn.Rows.Add(newRow); }
为什么原来的代码不行?
你之前的select new { d1, d2 }是把两个DataRow包装成了一个匿名对象,直接处理这个对象的话,并不会自动把两个行的字段展开到同一行,而是会把d1和d2作为两个独立的属性,最终导致结果表结构不符合预期。上面的代码通过手动遍历列的方式,把两个行的字段都合并到了同一个新行里,完美适配dtFormData的动态列场景。
如果你的两个表确定没有重复列名,可以去掉前缀的逻辑,直接用原列名即可。
内容的提问来源于stack exchange,提问作者aas
相关产品推荐
相关产品推荐

