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

Dapper DynamicParameters.ParameterNames无法在foreach循环中迭代的问题

解决Dapper DynamicParameters参数日志记录问题

问题根源

用new DynamicParameters(匿名对象)初始化的参数,其ParameterNames集合仅包含手动通过Add方法添加的参数;通过对象模板初始化的参数会被存储在内部的templates集合中,不会被纳入ParameterNames,因此遍历该集合无法获取参数值。

更优解决方案:利用Dapper原生方法加载参数

无需反射,直接借助DynamicParameters实现的IDynamicParameters接口方法,将参数加载到临时DbCommand中,再从命令的参数集合提取信息:

private IEnumerable<SqlParameter> ConvertDynamicParameters(DynamicParameters dynamicParams)
{
    using var cmd = new SqlCommand(); // 可根据数据库类型创建对应DbCommand
    dynamicParams.AddParameters(cmd, null); // 让Dapper自动将所有参数加载到命令中
    
    foreach (SqlParameter param in cmd.Parameters)
    {
        yield return new SqlParameter(param.ParameterName, param.Value);
    }
}

该方案依赖Dapper自身的参数映射逻辑,不会因内部字段变更失效,稳定性更高。

反射方案的可行性与实现

反射遍历templates的方案可行,但需注意Dapper版本迭代可能导致内部字段名变更,存在维护风险。以下是Dapper 2.x版本的示例实现:

private IEnumerable<(string Name, object Value)> ExtractTemplateParameters(DynamicParameters dynamicParams)
{
    // 获取内部的_templates字段
    var templatesField = typeof(DynamicParameters).GetField("_templates", BindingFlags.NonPublic | BindingFlags.Instance);
    if (templatesField == null) yield break;
    
    var templates = (IEnumerable)templatesField.GetValue(dynamicParams);
    foreach (var template in templates)
    {
        // 获取模板中存储的匿名对象
        var valueProp = template.GetType().GetProperty("Value");
        if (valueProp == null) continue;
        
        var paramObj = valueProp.GetValue(template);
        if (paramObj == null) continue;
        
        // 遍历匿名对象属性提取参数名和值
        foreach (var prop in paramObj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
        {
            yield return (prop.Name, prop.GetValue(paramObj));
        }
    }
}

若后续Dapper更新修改了内部字段名(比如_templates),需同步调整代码。

额外建议

如果需要记录最终执行的带参数SQL,可结合CommandDefinition和Dapper的参数替换逻辑生成日志字符串,但注意仅用于日志,不可直接执行(避免SQL注入风险)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 03:05:04