如何使用Dapper插入多条含相同外键的数据
使用Dapper批量插入多条子表数据(含相同外键)
要实现给关联同一父表的子表批量插入数据,Dapper本身支持直接传入对象集合完成批量操作,核心是确保子表对象包含关联父表的外键字段,并在SQL语句中对应处理外键的插入逻辑。
问题分析
你当前的代码存在两个关键缺失:
- 子表
LocationInformation必然需要一个关联父表的外键字段(比如AssessmentId),但你的INSERT语句和对象列表都未包含该字段,导致插入的数据无法关联到目标父表。 - 虽然Dapper的
ExecuteAsync支持集合批量执行,但需要集合内每个对象都覆盖SQL语句中用到的所有参数。
修正后的实现步骤
1. 给子表模型添加外键属性
修改LocationInformationModel,补充关联父表的外键字段:
public class LocationInformationModel { public Guid LocationInformationId { get; set; } public string Address1 { get; set; } public string Address2 { get; set; } public string City { get; set; } public string State { get; set; } public string Zip { get; set; } // 新增父表外键,关联父表主键 public Guid AssessmentId { get; set; } }
2. 构建带相同外键的子表对象列表
填充locationInformationModels时,给每个子对象设置相同的父表ID(即外键值):
// 假设父表已存在的主键为assessmentId(实际场景中从父表获取) var assessmentId = Guid.NewGuid(); assessmentModel.locationInformationModels = new List<LocationInformationModel> { new LocationInformationModel { LocationInformationId = Guid.NewGuid(), Address1 = "XX街道XX号", City = "XX市", State = "XX省", Zip = "100000", AssessmentId = assessmentId // 绑定相同外键 }, new LocationInformationModel { LocationInformationId = Guid.NewGuid(), Address1 = "YY路YY号", City = "YY市", State = "YY省", Zip = "200000", AssessmentId = assessmentId // 绑定相同外键 } };
3. 更新SQL插入语句,包含外键字段
修改INSERT语句,加入外键字段的插入逻辑:
string sqlStatement = @"INSERT INTO LocationInformation ([LocationInformationId] ,[AssessmentId] -- 新增外键字段 ,[Address1] ,[Address2] ,[City] ,[State] ,[Zip]) VALUES( @LocationInformationId,@AssessmentId,@Address1,@Address2,@City,@State,@Zip)";
4. 执行批量插入(你的原有执行逻辑可直接复用)
Dapper会自动遍历集合中的每个对象,将参数绑定到SQL语句并批量执行,配合事务保证操作的原子性:
using (var connection = new SqlConnection(_connectionString)) { await connection.OpenAsync(); using (var ts = connection.BeginTransaction()) { // 传入对象集合,Dapper自动处理批量插入 var retVal = await connection.ExecuteAsync(sqlStatement, assessmentModel.locationInformationModels, transaction: ts); ts.Commit(); return retVal; // 返回成功插入的行数 } }
额外优化建议
- 如果
LocationInformationId是数据库自增主键(比如IDENTITY),可以从SQL语句和模型中移除该字段的插入逻辑,由数据库自动生成ID,减少手动操作的冗余。 - Dapper的
ExecuteAsync针对集合参数做了内部优化,效率远高于循环执行单条插入,无需额外手动拆分批量。
内容的提问来源于stack exchange,提问作者CodeMan03
相关产品推荐
相关产品推荐

