Как я Параметризовал пустую строку с DBNull. Значение ясно и быстро

Я устал от написания следующего кода:

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

но это не будет работать потому что "Оператор'??' не может быть применен к операндам типа 'строка и 'Система. DBNull'".

У меня есть C# 3.5 и SQL Server 2005 в моем распоряжении, если он имеет значение.

35
задан David Murdoch 8 April 2010 в 21:03
поделиться

5 ответов

Приведите любое из ваших значений к объекту , и он будет компилироваться.

myCmd.Parameters.Add("@MiddleName", MiddleName==null ? (object)DBNull.Value : MiddleName);
56
ответ дан 27 November 2019 в 06:37
поделиться

Да, мы все хотели бы сделать myCmd.Parameters.Add ("@ MiddleName", MiddleName ?? DBNull.Value); . Или, что еще лучше, пусть этот чертов уровень SqlClient понимает, что CLR null должен отображаться в DBNull.Value при добавлении параметра. К сожалению, система типов .Net закрывает первую альтернативу, а реализация SqlClient закрывает вторую.

Я бы выбрал хорошо известное имя функции, например Coalesce или IsNull . Любой разработчик БД сразу узнает, что он делает, по названию.

1
ответ дан 27 November 2019 в 06:37
поделиться

Я бы предпочел дать вам два совершенно разных предложения:

  1. Используйте ORM. Существует множество ненавязчивых инструментов ORM.

  2. Напишите свою собственную оболочку для построения команд с более понятным интерфейсом. Что-то вроде:

     публичный класс MyCommandRunner {
    приватный SqlCommand cmd; 
     
    публичный MyCommandRunner (string commandText) {
    cmd = new SqlCommand (commandText); { {1}}} 
     
    public void AddParameter (строковое имя, строковое значение) {
    if (value == null) 
    cmd.Parameters.Add (name , DBNull.Value); 
    else 
    cmd.Parameters.Add (name, value); 
    } 
     
     // ... больше AddParameter перегружает 
    } 
     

Если вы переименуете свои методы AddParameter только в Add , вы сможете использовать его очень удобно:

var cmd = new MyCommand("INSERT ...")
  {
    { "@Param1", null },
    { "@Param2", p2 }
  };
1
ответ дан 27 November 2019 в 06:37
поделиться

Я бы предложил использовать свойства, допускающие значение NULL, вместо общедоступных полей и метода 'AddParameter' (не знаю, оптимизирован ли этот код или правильный, просто вне в верхней части моей головы):


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
ответ дан 27 November 2019 в 06:37
поделиться

Лично я бы сделал это с методом расширения (убедитесь, что он входит в статический класс)

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

Тогда у вас будет

myCmd.Parameters.Add("@MiddleName", MiddleName.GetStringOrDBNull());
11
ответ дан 27 November 2019 в 06:37
поделиться