Подтвердить что ты не робот

Как я могу быстро и быстро параметризовать нулевую строку с помощью DBNull.Value

Мне надоело писать следующий код:

/* 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".

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

4b9b3361

Ответ 1

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

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

Ответ 2

Вы можете избежать явного приведения в 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

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

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

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

myCmd.Parameters.Add("@MiddleName", MiddleName.GetStringOrDBNull());

Ответ 4

myCmd.Parameters.Add("@MiddleName", MiddleName ?? (object)DBNull.Value);

Ответ 5

@David Спасибо за ваше предложение. Следующий метод отлично работает!

MiddleName ?? (object)DBNull.Value

Ответ 6

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

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

Ответ 7

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

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

  • Создайте собственную оболочку для создания команд с помощью более чистого интерфейса. Что-то вроде:

    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

Я бы предложил использовать свойства с нулевым значением вместо общедоступных полей и метод 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);