如何处理Excel模板导入的DataTable,按编号规整存入双数据库表?
我来帮你搞定这个按编号处理DataTable数据并存入数据库的问题,核心思路是按编号分组后依次处理,这样就能解决数据对齐的问题了,下面是具体的实现步骤和代码示例:
解决思路
- 先把DataTable里的数据按编号分组,确保同一编号的培训和参与者数据绑定在一起
- 按编号从小到大排序分组,保证处理顺序是编号1→编号2→...依次进行
- 对每个分组,先处理该编号的培训详情数据,插入到培训详情表后获取关联ID,再遍历分组内的所有行处理参与者信息,关联培训ID存入参与者表
代码实现(C#示例)
首先要引用System.Linq命名空间,然后按以下逻辑编写代码:
// 1. 按编号分组并按编号升序排序,确保处理顺序正确 var groupedData = dtsel.AsEnumerable() .GroupBy(row => row.Field<int>("编号")) // 这里假设编号是int类型,根据实际改为string等 .OrderBy(group => group.Key); // 遍历每个编号分组 foreach (var numberGroup in groupedData) { int trainingRecordId = 0; var firstRow = numberGroup.First(); // 假设同一编号的培训详情字段一致,取第一条即可 // --- 第一步:插入培训详情到数据库 --- using (var conn = new SqlConnection("你的数据库连接字符串")) { conn.Open(); // 使用事务保证数据一致性,避免培训详情插入成功但参与者插入失败的情况 using (var transaction = conn.BeginTransaction()) { try { // 构造培训详情的插入SQL(参数化避免SQL注入) string insertTrainingSql = @" INSERT INTO 培训详情表 (编号, 培训名称, 培训时间, 培训地点) VALUES (@Number, @TrainingName, @TrainingTime, @TrainingLocation); SELECT SCOPE_IDENTITY(); -- 获取自增的培训ID "; using (var cmd = new SqlCommand(insertTrainingSql, conn, transaction)) { // 添加参数,根据你的Excel字段和数据库表字段调整 cmd.Parameters.AddWithValue("@Number", firstRow.Field<int>("编号")); cmd.Parameters.AddWithValue("@TrainingName", firstRow.Field<string>("培训名称")); cmd.Parameters.AddWithValue("@TrainingTime", firstRow.Field<DateTime>("培训时间")); cmd.Parameters.AddWithValue("@TrainingLocation", firstRow.Field<string>("培训地点")); // 其他培训详情字段... // 执行插入并获取培训ID trainingRecordId = Convert.ToInt32(cmd.ExecuteScalar()); } // --- 第二步:插入当前编号下的所有参与者信息 --- string insertParticipantSql = @" INSERT INTO 参与者信息表 (培训ID, 参与者姓名, 联系方式, 所属部门) VALUES (@TrainingId, @ParticipantName, @Contact, @Department); "; foreach (var participantRow in numberGroup) { using (var cmd = new SqlCommand(insertParticipantSql, conn, transaction)) { cmd.Parameters.AddWithValue("@TrainingId", trainingRecordId); cmd.Parameters.AddWithValue("@ParticipantName", participantRow.Field<string>("参与者姓名")); cmd.Parameters.AddWithValue("@Contact", participantRow.Field<string>("联系方式")); cmd.Parameters.AddWithValue("@Department", participantRow.Field<string>("所属部门")); // 其他参与者字段... cmd.ExecuteNonQuery(); } } // 提交事务 transaction.Commit(); Console.WriteLine($"编号{numberGroup.Key}的数据处理完成"); } catch (Exception ex) { // 异常回滚事务 transaction.Rollback(); Console.WriteLine($"处理编号{numberGroup.Key}的数据失败:{ex.Message}"); // 可以在这里添加日志记录等操作 throw; // 可选:抛出异常让上层处理 } } } }
注意事项
- 字段匹配:代码中的字段名称(比如"编号"、"培训名称")要和你的DataTable列名、数据库表字段完全一致,根据实际情况调整。
- 数据类型:如果编号是字符串类型,把
Field<int>改成Field<string>,同时调整SQL参数的类型。 - 事务处理:示例中加入了事务,确保同一编号的培训详情和参与者数据要么都插入成功,要么都回滚,避免数据不一致。
- 性能优化:如果数据量很大,可以考虑批量插入参与者信息,减少数据库连接次数,比如用
SqlBulkCopy或者拼接批量插入SQL(注意保持参数化避免注入)。
内容的提问来源于stack exchange,提问作者user3074125
相关产品推荐
相关产品推荐

