有没有一种方法可以遍历Dapper DynamicParameters对象?

16

我需要制作一个通用的记录器,记录特定的插入/更新语句,以便我的测试人员可以验证被插入数据的正确性。

我最初的想法是使用一个接受DynamicParameters的函数,并通过foreach循环遍历DynamicParameters,生成一个字符串来列出参数的名称和值,并使它们更容易被测试人员阅读。

不幸的是,Dapper.DynamicParameters没有公共定义"GetEnumerator"的方法。

以下是我希望实现的基本示例:

string myFormattedListofParameters = "";
foreach (var p in myDynamicParameters)
{
myFormattedListofParameters += p.Name + "=" + p.Value.ToString();
}
4个回答

21

尝试:

            var sb = new StringBuilder();
            foreach (var name in p.ParameterNames)
            {
                var pValue = p.Get<dynamic>(name);
                sb.AppendFormat("{0}={1}\n", name, pValue.ToString());
            }

谢谢你的帮助,Sam。顺便说一句,我喜欢Dapper,它为我节省了很多时间和烦恼。当我尝试上面的代码时,我得到了一个错误信息:'Dapper.DynamicParameters'不包含“ParameterNames”的定义。 - SLoret
7
当我按照你的代码操作时,遇到了以下异常:[NullReferenceException: Object reference not set to an instance of an object.]。其中的 Dapper.DynamicParameters.Get(String name) 函数位于 c:\Dev\Dapper\Dapper\SqlMapper.cs 的第2574行。请问这是什么问题? - Gary Brunton
2
我也遇到了和Gary一样的异常。这个问题有任何更新吗? - Adam Levitt
这个问题还在困扰着我,要求用哪个版本的Dapper才能使其正常工作? - Adam Levitt
最新的NuGet中,在DynamicParameters上调用Get<T>时仍然会出现SQLMapper.cs空引用。关于这个问题有什么最新消息吗? - Brendon Bezuidenhout
6
我认为Get<T>(string name)函数只有在将IDbDataParameter实例附加到参数后才能正常运行。换句话说,在执行Execute、Query或其他类似的函数之前,无法获取参数的值。如果在使用参数之前调用Get<T>(string name),会出现空引用异常。 - Bernard Chen

8
    string ParametersToString(DynamicParameters parameters)
    {
        var result = new StringBuilder();

        if (parameters != null)
        {
            var firstParam = true;
            var parametersLookup = (SqlMapper.IParameterLookup)parameters;
            foreach (var paramName in parameters.ParameterNames)
            {
                if (!firstParam)
                {
                    result.Append(", ");
                }
                firstParam = false;

                result.Append('@');
                result.Append(paramName);
                result.Append(" = ");
                try
                {
                    var value = parametersLookup[paramName];// parameters.Get<dynamic>(paramName);
                    result.Append((value != null) ? value.ToString() : "{null}");
                }
                catch
                {
                    result.Append("unknown");
                }
            }

        }
        return result.ToString();
    }

将类型转换为SqlMapper.IParameterLookup帮助我避免了在尝试在IDbConnection实例上使用集合之前迭代时出现的NullReferenceException。谢谢! - Derek Van Cuyk
谢谢您的帮助,在编写单元测试时,确保正确的参数被连接到调用我们的Dapper包装器中的正确值。 - nrjohnstone

1

使用Linq的一行代码:

string.Join(", ", from pn in sprocParams.ParameterNames select string.Format("@{0}={1}", pn, (sprocParams as SqlMapper.IParameterLookup)[pn]))

我正在使用log4net记录日志:
Log.InfoFormat("Exec {0} {1}", storedProc, string.Join(", ", from pn in sprocParams.ParameterNames select string.Format("@{0}={1}", pn, (sprocParams as SqlMapper.IParameterLookup)[pn])));

-3

以防万一,

var pmaster = new Dapper.DynamicParameters();                            
SortedList l = new SortedList();
l.Add("param1", object1);
l.Add("param2", object2);
l.Add("param3", object3);
l.Add("param4", object4);

foreach(var key in l.Keys)
{
  var val = l[key];
  pmaster.Add(key.ToString(), val);
}

对我有用。


这并不能帮助我封装抽象。如果我将其放在一个方法中,比如说FormatDynamicParameters,那么我现在需要所有的消费者传入一个DynamicParameters实例和一个IList实现。 - Derek Van Cuyk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接