You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Dapper批量执行Stored Procedure且无需循环调用Execute方法

问题原因分析

  • 第一次编写的代码问题:你在循环中重复往同一个DynamicParameters对象中添加同名参数,后续添加的参数会直接覆盖之前的同名参数,最终queryParameters中仅保留最后一条Person记录的参数值,因此仅最后一条数据被写入数据库。
  • 第二次直接传入Person数组报错的问题:存储过程定义的参数名为@id、@first_name、@last_name,但Person类的属性名为Id、FirstName、LastName,命名规则不匹配,Dapper自动映射时无法找到对应参数值,因此抛出参数不匹配错误。

正确实现方案

Dapper的Execute方法原生支持传入可枚举类型的参数集合,会自动遍历集合中的每个元素分别执行存储过程,无需手动将Execute放入循环中,你可以选择以下两种方案实现:

方案1:使用匹配参数名的匿名类集合(推荐,代码更简洁)

直接将Person集合转换为属性名和存储过程参数名完全匹配的匿名类集合,传入Execute方法即可:

public static int SaveData3() 
{
    var list = new List<Person>();
    var p1 = new Person() { Id = 20, FirstName = "Michiel", LastName = "De Ruyter" };
    var p2 = new Person() { Id = 21, FirstName = "Jacob", LastName = "Jakobsson" };
    list.Add(p1);
    list.Add(p2);

    // 转换为属性名和存储过程参数名匹配的匿名类集合
    var paramList = list.Select(p => new 
    {
        id = p.Id,
        first_name = p.FirstName,
        last_name = p.LastName
    }).ToList();

    using (IDbConnection connection = new OracleConnection(GetConnectionString()))
    {
        try
        {
            var affectedRows = connection.Execute("kwc_test_person_procedure",
                paramList,
                commandType: CommandType.StoredProcedure
            );
            Log.Information("Executed procedure to store data. Rows affected: {0}", affectedRows);
            return affectedRows;
        }
        catch (Exception ex)
        {
            Log.Error(ex.Message);
            Log.Error(ex.StackTrace);
            throw;
        }
    }
}

方案2:使用DynamicParameters集合

如果需要用到DynamicParameters的特殊能力(如指定参数类型、添加输出参数),可以构造DynamicParameters集合传入:

public static int SaveData3() 
{
    var list = new List<Person>();
    var p1 = new Person() { Id = 20, FirstName = "Michiel", LastName = "De Ruyter" };
    var p2 = new Person() { Id = 21, FirstName = "Jacob", LastName = "Jakobsson" };
    list.Add(p1);
    list.Add(p2);

    var paramList = new List<DynamicParameters>();
    foreach (var item in list)
    {
        var queryParameters = new DynamicParameters();
        queryParameters.Add("@id", item.Id);
        queryParameters.Add("@first_name", item.FirstName);
        queryParameters.Add("@last_name", item.LastName);
        paramList.Add(queryParameters);
    }

    using (IDbConnection connection = new OracleConnection(GetConnectionString()))
    {
        try
        {
            var affectedRows = connection.Execute("kwc_test_person_procedure",
                paramList,
                commandType: CommandType.StoredProcedure
            );
            Log.Information("Executed procedure to store data. Rows affected: {0}", affectedRows);
            return affectedRows;
        }
        catch (Exception ex)
        {
            Log.Error(ex.Message);
            Log.Error(ex.StackTrace);
            throw;
        }
    }
}

两种方案执行后返回的受影响行数等于你传入的Person集合长度,所有数据都会正常写入数据库。

内容的提问来源于stack exchange,提问作者KWC

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.15 19:27:05