代码之家  ›  专栏  ›  技术社区  ›  David Murdoch

如何用DBNull.Value清晰快速地参数化空字符串

  •  31
  • David Murdoch  · 技术社区  · 14 年前

    我厌倦了编写以下代码:

    /* Commenting out irrelevant parts
    public string MiddleName;
    public void Save(){
        SqlCommand = new SqlCommand();
        // blah blah...boring INSERT statement with params etc go here. */
        if(MiddleName==null){
            myCmd.Parameters.Add("@MiddleName", DBNull.Value);
        }
        else{
            myCmd.Parameters.Add("@MiddleName", MiddleName);
        }
        /*
        // more boring code to save to DB.
    }*/
    

    public static object DBNullValueorStringIfNotNull(string value)
    {
        object o;
        if (value == null)
        {
            o = DBNull.Value;
        }
        else
        {
            o = value;
        }
        return o;
    }
    
    // which would be called like:
    myCmd.Parameters.Add("@MiddleName", DBNullValueorStringIfNotNull(MiddleName));
    

    如果这是一个很好的方法去做这件事,那么你会建议什么作为方法名? 有点冗长和混乱。

    我也对完全缓解这个问题的方法持开放态度。我很乐意这样做:

    myCmd.Parameters.Add("@MiddleName", MiddleName==null ? DBNull.Value : MiddleName);
    

    但这不起作用,因为“运算符'??'不能应用于'string和'System.DBNull'类型的操作数。

    如果需要的话,我可以使用C#3.5和SQL Server 2005。

    8 回复  |  直到 14 年前
        1
  •  58
  •   Kiquenet user385990    11 年前

    把你的价值观 object

    myCmd.Parameters.Add("@MiddleName", MiddleName==null ? (object)DBNull.Value : MiddleName);
    
        2
  •  23
  •   Lukas S.    10 年前

    您可以避免显式强制转换为 object 使用 SqlString.Null 而不是 DBNull.Value :

    MiddleName ?? SqlString.Null
    

    int、datetime等都有相应的类型。下面是一段代码片段,还有几个示例:

     cmd.Parameters.AddWithValue("@StartDate", StartDate ?? SqlDateTime.Null);
     cmd.Parameters.AddWithValue("@EndDate", EndDate ?? SqlDateTime.Null);
     cmd.Parameters.AddWithValue("@Month", Month ?? SqlInt16.Null);
     cmd.Parameters.AddWithValue("@FormatID", FormatID ?? SqlInt32.Null);
     cmd.Parameters.AddWithValue("@Email", Email ?? SqlString.Null);
     cmd.Parameters.AddWithValue("@ZIP", ZIP ?? SqlBoolean.Null);
    
        3
  •  12
  •   Chris Marisic    14 年前

    public static object GetStringOrDBNull(this string obj)
    {
        return string.IsNullOrEmpty(obj) ? DBNull.Value : (object) obj
    }
    

    myCmd.Parameters.Add("@MiddleName", MiddleName.GetStringOrDBNull());
    
        4
  •  6
  •   hamid reza mansouri    9 年前
    myCmd.Parameters.Add("@MiddleName", MiddleName ?? (object)DBNull.Value);
    
        5
  •  2
  •   Sagar    10 年前

    @大卫谢谢你的建议。下面的方法非常有效!

    MiddleName ?? (object)DBNull.Value
    
        6
  •  1
  •   Remus Rusanu    14 年前

    myCmd.Parameters.Add("@MiddleName", MiddleName ?? DBNull.Value); . 或者更好的是,让奇怪的SqlClient层理解CLR null 应映射到 DBNull.Value 添加参数时。不幸的是.Net类型的系统关闭了第一个选项,而SqlClient的实现关闭了第二个选项。

    我会用一个众所周知的函数名,比如 Coalesce IsNull . 任何数据库开发人员都会在一瞬间意识到他们所做的事情,仅从名称就可以了。

        7
  •  1
  •   Fábio Batista Raza Ahmed    14 年前

    我想给你两个完全不同的建议:

    1. 使用更干净的界面编写自己的用于生成命令的包装器。比如:

      public class MyCommandRunner {
        private SqlCommand cmd;
      
        public MyCommandRunner(string commandText) {
          cmd = new SqlCommand(commandText);
        }
      
        public void AddParameter(string name, string value) {
          if (value == null)
           cmd.Parameters.Add(name, DBNull.Value);
          else
            cmd.Parameters.Add(name, value);
        }
      
        // ... more AddParameter overloads
      }
      

    AddParameter 方法 Add ,您可以非常巧妙地使用它:

    var cmd = new MyCommand("INSERT ...")
      {
        { "@Param1", null },
        { "@Param2", p2 }
      };
    
        8
  •  1
  •   Kiquenet user385990    11 年前

    
    private string m_MiddleName;
    
    public string MiddleName
    {
      get { return m_MiddleName; }
      set { m_MiddleName = value; }
    }
    
    .
    .
    .
    
    public static void AddParameter(SQLCommand cmd, string parameterName, SQLDataType dataType, object value)
    {
      SQLParameter param = cmd.Parameters.Add(parameterName, dataType);
    
      if (value is string) { // include other non-nullable datatypes
        if (value == null) {
          param.value = DBNull.Value;
        } else {
          param.value = value;
        }
      } else { 
    
        // nullable data types
        // UPDATE: HasValue is for nullable, not object type
        if (value.HasValue) // {{{=====================================================
        {
              param.value = value;
        } else 
        {
              param.value = DBNull.Value;
        }
      }
    }
    
    .
    .
    .
    AddParameter(cmd, "@MiddleName", SqlDbType.VarChar, MiddleName);