如何对比两个DataTable并添加Issued列至GridView展示?
解决方案:给合并后的DataTable添加Issued列并绑定到GridView
没问题,我来帮你搞定这个需求!其实整个流程分成构建目标表结构和填充数据并判断Issued状态两步就好,而且用LINQ确实能让代码更简洁,我给你两种实现方式,你可以根据自己的习惯选:
第一步:先搭建目标DataTable的结构
你已经创建了空DataTable,现在需要把原有的ID、Receipt、Amount列加上,再新增Issued列。注意列的类型要和A、B表对应(比如ID是int还是string,根据你的实际情况调整):
// 假设你的空表叫dtResult dtResult.Columns.Add("ID", typeof(int)); // 替换成你实际的ID类型,比如typeof(string) dtResult.Columns.Add("Receipt", typeof(string)); dtResult.Columns.Add("Amount", typeof(decimal)); dtResult.Columns.Add("Issued", typeof(string)); // 新增的状态列
第二步:填充数据并设置Issued值
这里推荐两种方法,第一种是高效的HashSet查找+循环(数据量大的时候性能更好),第二种是纯LINQ写法:
方法1:HashSet+循环(性能优先)
先把B表的所有ID提取到HashSet里(因为HashSet的Contains方法是O(1)时间复杂度,比直接遍历B表快很多),然后遍历A表的每一行,判断ID是否存在,再填充到目标表:
// 提取B表的所有ID到HashSet,注意处理可能的空值 var bIds = new HashSet<object>( B.AsEnumerable() .Where(row => !row.IsNull("ID")) // 过滤空ID .Select(row => row["ID"]) ); // 遍历A表的每一行,填充到目标表 foreach (DataRow aRow in A.Rows) { DataRow newRow = dtResult.NewRow(); // 复制原有列的值 newRow["ID"] = aRow["ID"]; newRow["Receipt"] = aRow["Receipt"]; newRow["Amount"] = aRow["Amount"]; // 判断Issued状态:如果A的ID在B的HashSet里,就设为Yes,否则No newRow["Issued"] = bIds.Contains(aRow["ID"]) ? "Yes" : "No"; // 把新行加入目标表 dtResult.Rows.Add(newRow); }
方法2:纯LINQ写法(代码更简洁)
用LINQ的join语法,把A表和B表按ID关联,然后判断是否有匹配的行,直接生成目标表的行:
var resultRows = from aRow in A.AsEnumerable() // 用join...into做左连接,获取A行对应的所有B行 join bRow in B.AsEnumerable() on aRow["ID"] equals bRow["ID"] into matchingRows // 生成目标表的行数据 select dtResult.LoadDataRow(new object[] { aRow["ID"], aRow["Receipt"], aRow["Amount"], // 如果有匹配的B行,就是Yes,否则No matchingRows.Any() ? "Yes" : "No" }, false); // 把LINQ结果转换为DataTable dtResult = resultRows.CopyToDataTable();
最后:绑定到GridView
数据填充完之后,直接把目标表绑到GridView就行:
GridView1.DataSource = dtResult; GridView1.DataBind();
小提醒
- 确保A和B表的
ID列数据类型一致,不然比较会出错(比如一个是int一个是string); - 如果ID可能为空,记得在提取HashSet或者LINQ查询里过滤空值,避免出现意外错误。
内容的提问来源于stack exchange,提问作者Laba Ningombam
相关产品推荐
相关产品推荐

