C#中如何更简洁地检测DataRow的BusNumber列变化并分组处理?
问题描述
我对SchoolBus和SchoolPupil两张表执行了如下SQL查询:
Select SB.BusNumber, SB.BusDriverLastName, SB.BusDriverFirstName, SP.LastName, SP.FirstName, SP.HomeTown, SP.Age, SP.BusFare From SchoolBus As SB Inner Join SchoolPupil As SP On SP.BusNumber = SB.BusNumber Order By SB.BusNumber, SP.HomeTown
我需要在C#应用中读取该查询结果,针对每个BusNumber对应的所有数据行,对家乡和公交费用执行复杂计算,这意味着需要检测每个BusNumber对应的最后一行。
目前我已通过如下代码实现:
for (int z_intIdx = 0; z_intIdx < z_dstData.Tables[0].Rows.Count; z_intIdx++) { // 处理DataRow并将其存入IEnumerable备用 if (z_intIdx == z_dstData.Tables[0].Rows.Count - 1 || z_dstData.Tables[0].Rows[z_intIdx] != z_dstData.Tables[0].Rows[z_intIdx + 1]) { // 对IEnumerable执行复杂计算 } }
但我认为可能存在DataTable、DataRow或DataRowCollection中的方法或属性,能实现更简洁的逻辑,允许使用foreach或while循环。请问是否有可替代上述代码的实现方式?
可行的替代实现方式
方案1:LINQ分组(最简洁)
既然查询结果已经按BusNumber排序,直接用LINQ的GroupBy按BusNumber分组,每组就是同一班车的所有学生数据,无需手动判断最后一行,处理完每组后直接执行计算即可:
var groupedData = z_dstData.Tables[0].AsEnumerable() .GroupBy(row => row.Field<int>("BusNumber")); // 根据实际数据类型调整,比如string类型 foreach (var group in groupedData) { var currentBusRows = group.ToList(); // 处理currentBusRows中的每一行并存入IEnumerable // 直接对当前班车的所有数据执行复杂计算 }
方案2:foreach循环跟踪当前BusNumber
如果不想用LINQ,可以用foreach循环,通过变量跟踪当前的BusNumber,当遇到不同编号或遍历到最后一行时触发计算:
if (z_dstData.Tables[0].Rows.Count == 0) return; int currentBusNumber = z_dstData.Tables[0].Rows[0].Field<int>("BusNumber"); List<DataRow> currentBusRows = new List<DataRow>(); foreach (DataRow row in z_dstData.Tables[0].Rows) { int rowBusNumber = row.Field<int>("BusNumber"); if (rowBusNumber != currentBusNumber) { // 对currentBusRows执行复杂计算 // 重置跟踪变量 currentBusNumber = rowBusNumber; currentBusRows.Clear(); } currentBusRows.Add(row); } // 处理最后一组数据 if (currentBusRows.Count > 0) { // 对currentBusRows执行复杂计算 }
方案3:利用DataView确保排序(可选)
如果担心查询结果的排序可能失效,可以先通过DataView重新按BusNumber排序,再按上述方式处理:
DataView sortedView = z_dstData.Tables[0].DefaultView; sortedView.Sort = "BusNumber, HomeTown"; // 后续遍历sortedView,逻辑同方案1或方案2
原代码的问题说明
你当前代码中的z_dstData.Tables[0].Rows[z_intIdx] != z_dstData.Tables[0].Rows[z_intIdx + 1]是错误的——这是比较DataRow对象的引用,而非BusNumber字段的值,会导致判断逻辑完全失效,必须改为比较BusNumber的实际值才正确。
内容的提问来源于stack exchange,提问作者Jean-David Lanz
相关产品推荐
相关产品推荐

