Ответ 1
Передайте любое из ваших значений в object
, и оно будет скомпилировано.
myCmd.Parameters.Add("@MiddleName", MiddleName==null ? (object)DBNull.Value : MiddleName);
Мне надоело писать следующий код:
/* 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 в моем распоряжении, если это имеет значение.
Передайте любое из ваших значений в object
, и оно будет скомпилировано.
myCmd.Parameters.Add("@MiddleName", MiddleName==null ? (object)DBNull.Value : MiddleName);
Вы можете избежать явного приведения в 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);
Лично это то, что я сделал бы с помощью метода расширения (убедитесь, что это входит в статический класс)
public static object GetStringOrDBNull(this string obj)
{
return string.IsNullOrEmpty(obj) ? DBNull.Value : (object) obj
}
Тогда у вас будет
myCmd.Parameters.Add("@MiddleName", MiddleName.GetStringOrDBNull());
myCmd.Parameters.Add("@MiddleName", MiddleName ?? (object)DBNull.Value);
@David Спасибо за ваше предложение. Следующий метод отлично работает!
MiddleName ?? (object)DBNull.Value
Yeap, мы все хотели бы сделать myCmd.Parameters.Add("@MiddleName", MiddleName ?? DBNull.Value);
. Или еще лучше, чтобы уровень fqqlqlqqqqqq был понят, что CLR null
должен быть сопоставлен с DBNull.Value
при добавлении параметра. К сожалению, система типа .Net закрывает первый вариант, а реализация SqlClient закрывает вторую.
Я бы пошел с хорошо известным именем функции, например Coalesce или IsNull. Любой разработчик БД распознает то, что они делают в одно мгновение, только от имени.
Я бы лучше дал вам два совершенно разных предложения:
Используйте 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 }
};
Я бы предложил использовать свойства с нулевым значением вместо общедоступных полей и метод 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);