web-dev-qa-db-ja.com

DBNull.Valueを使用してnull文字列を明確かつ迅速にパラメーター化する方法

次のコードを書くのに飽きました。

/* 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));

これがこれを行うのに良い方法である場合、メソッド名として何を提案しますか?DBNullValueorStringIfNotNullは少し冗長で混乱します。

私はまた、この問題を完全に緩和する方法を受け入れています。私はこれをするのが大好きです:

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

しかし、「演算子 '??」タイプ 'stringおよび' System.DBNull '"のオペランドには適用できません。

必要に応じて、C#3.5とSQL Server 2005を自由に利用できます。

36
David Murdoch

どちらかの値をobjectにキャストすると、コンパイルされます。

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

SqlString.Nullの代わりにDBNull.Valueを使用すると、objectへの明示的なキャストを回避できます。

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);
19
Sergey K

個人的にこれは私が拡張メソッドで行うことです(これが静的クラスに入るようにしてください)

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

それならあなたは

myCmd.Parameters.Add("@MiddleName", MiddleName.GetStringOrDBNull());
12
Chris Marisic
myCmd.Parameters.Add("@MiddleName", MiddleName ?? (object)DBNull.Value);
6

@Davidご提案ありがとうございます。次の方法はうまくいきます!

MiddleName ?? (object)DBNull.Value
2
Sagar

まったく異なる2つの提案をしたいと思います。

  1. ORMを使用します。邪魔にならないORMツールはたくさんあります。

  2. よりクリーンなインターフェースで、コマンドを作成するための独自のラッパーを作成します。何かのようなもの:

    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 }
  };
1
Fábio Batista

私はパブリックフィールドと 'AddParameter'メソッドの代わりにnull可能なプロパティを使用することをお勧めします(このコードが最適化されているか、正しいかわからないので、頭上から):


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);

1
user113476

うん、私たちはmyCmd.Parameters.Add("@MiddleName", MiddleName ?? DBNull.Value);をしたいです。または、もっと良いのは、CLR nullDBNull.Valueパラメータを追加する場合。残念ながら、.Net型システムは最初の選択肢を閉じ、SqlClientの実装は2番目を閉じます。

CoalesceIsNull のようなよく知られた関数名を使用します。すべてのDB開発者は、名前だけで、彼らが何をしているかを瞬時に認識します。

1
Remus Rusanu