【问题标题】:Is there anyway to iterate through a Dapper DynamicParameters object?无论如何要遍历 Dapper DynamicParameters 对象吗?
【发布时间】:2012-05-08 15:07:16
【问题描述】:

我需要制作一个通用记录器来记录某些插入/更新语句,以便我的测试人员可以验证插入的数据是否正确。

我的第一个想法是,我将只使用一个接受 DynamicParameters 的函数,然后我会遍历 DynamicParameters 以生成一个字符串来列出参数的名称和值,并使测试人员更容易阅读它们。

不幸的是,Dapper.DynamicParameters 不包含“GetEnumerator”的公共定义

这是我希望做的基本示例:

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

【问题讨论】:

    标签: dapper


    【解决方案1】:

    试试:

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

    【讨论】:

    • 感谢山姆的帮助。顺便说一句,爱 Dapper,它为我节省了很多时间和头痛。当我尝试上面的代码时,我得到......“Dapper.DynamicParameters”不包含“ParameterNames”的定义。
    • @Sam Saffron 当我遵循您的代码时,我收到以下异常:[NullReferenceException: Object reference not set to an instance of an object.] Dapper.DynamicParameters.Get(String name) in c :\Dev\Dapper\Dapper\SqlMapper.cs:2574
    • 我在这里遇到了与 Gary 相同的异常。有这方面的更新吗?
    • 这个问题仍然存在——这需要什么版本的 Dapper 才能工作?
    • 我相信 Get&lt;T&gt;(string name) 函数只有在 IDbDataParameter 实例附加到参数后才有效。换句话说,只有在参数用于执行或查询或其他类似功能时,才能获得值。如果在使用参数之前调用Get&lt;T&gt;(string name),则会得到空引用异常。
    【解决方案2】:

    与 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】:
          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。谢谢!
      • 感谢您,在编写单元测试时提供了帮助,这些单元测试断言正确的参数在调用我们的 Dapper 包装器时连接到正确的值
      【解决方案4】:

      以防万一,

      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 实现。
      猜你喜欢
      • 2016-08-12
      • 2011-01-08
      • 1970-01-01
      • 2021-05-08
      • 2013-01-01
      • 2019-06-07
      • 1970-01-01
      • 2011-09-05
      相关资源
      最近更新 更多