Присвоение null параметру SqlParameter

следующий код дает ошибку - " нет неявного преобразования из DBnull в int."

SqlParameter[] parameters = new SqlParameter[1];    
SqlParameter planIndexParameter = new SqlParameter("@AgeIndex", SqlDbType.Int);
planIndexParameter.Value = (AgeItem.AgeIndex== null) ? DBNull.Value : AgeItem.AgeIndex;
parameters[0] = planIndexParameter;

17 ответов


проблема в том, что ?: оператор не может определить тип возврата, потому что вы либо возвращаете int значение или значение типа DBNull, которые несовместимы.

вы можете, конечно, привести экземпляр AgeIndex к типу object, который удовлетворял бы ?: требование.

можно использовать ?? нуль-коалесцирующий оператор следующим образом

SqlParameter[] parameters = new SqlParameter[1];     
SqlParameter planIndexParameter = new SqlParameter("@AgeIndex", SqlDbType.Int);
planIndexParameter.Value = (object)AgeItem.AgeIndex ?? DBNull.Value;
parameters[0] = planIndexParameter; 

вот цитата из документация MSDN для ?: оператор, который объясняет проблему

тип first_expression и second_expression должны быть одинаковыми, или должно существовать неявное преобразование из одного типа в другой.


принятый ответ предлагает использовать гипс. Однако большинство типов SQL имеют специальное поле Null, которое можно использовать, чтобы избежать этого приведения.

например, SqlInt32.Null " представляет DBNull, который может быть назначен этому экземпляру класса SqlInt32."

int? example = null;
object exampleCast = (object) example ?? DBNull.Value;
object exampleNoCast = example ?? SqlInt32.Null;

вам нужно пройти DBNull.Значение в качестве параметра null в SQLCommand, если значение по умолчанию не указано в хранимой процедуре (если используется хранимая процедура). Лучший подход-назначить DBNull.Значение для любого отсутствующего параметра перед выполнением запроса и после foreach выполнит задание.

foreach (SqlParameter parameter in sqlCmd.Parameters)
{
    if (parameter.Value == null)
    {
        parameter.Value = DBNull.Value;
    }
}

в противном случае измените эту строку:

planIndexParameter.Value = (AgeItem.AgeIndex== null) ? DBNull.Value : AgeItem.AgeIndex;

следующим образом:

if (AgeItem.AgeIndex== null)
    planIndexParameter.Value = DBNull.Value;
else
    planIndexParameter.Value = AgeItem.AgeIndex;

потому что вы не можете использовать другой тип значения в условных утверждение, поскольку DBNull и int отличаются друг от друга. Надеюсь, это поможет.


С одной строкой кода попробуйте следующее:

var piParameter = new SqlParameter("@AgeIndex", AgeItem.AgeIndex ?? (object)DBNull.Value);

попробуйте это:

SqlParameter[] parameters = new SqlParameter[1];    
SqlParameter planIndexParameter = new SqlParameter("@AgeIndex", SqlDbType.Int);

planIndexParameter.IsNullable = true; // Add this line

planIndexParameter.Value = (AgeItem.AgeIndex== null) ? DBNull.Value : AgeItem.AgeIndex== ;
parameters[0] = planIndexParameter;

на мой взгляд, лучший способ сделать это с помощью параметры свойства sqlcommand, который класс:

public static void AddCommandParameter(SqlCommand myCommand)
{
    myCommand.Parameters.AddWithValue(
        "@AgeIndex",
        (AgeItem.AgeIndex== null) ? DBNull.Value : AgeItem.AgeIndex);
}

рассмотрите возможность использования структуры Nullable (T). Это позволит вам устанавливать значения, только если они у вас есть, и ваши объекты SQL Command распознают значение nullable и обрабатывают соответственно без проблем с вашей стороны.


если вы используете условный(троичный) оператор, компилятору требуется неявное преобразование между обоими типами, иначе вы получите исключение.

таким образом, вы можете исправить это, бросив один из обоих в System.Object:

planIndexParameter.Value = (AgeItem.AgeIndex== null) ? DBNull.Value : (object) AgeItem.AgeIndex;

но так как результат не очень красивый, и вы всегда должны помнить это литье, вы можете использовать такой метод расширения вместо:

public static object GetDBNullOrValue<T>(this T val)
{
    bool isDbNull = true;
    Type t = typeof(T);

    if (Nullable.GetUnderlyingType(t) != null)
        isDbNull = EqualityComparer<T>.Default.Equals(default(T), val);
    else if (t.IsValueType)
        isDbNull = false;
    else
        isDbNull = val == null;

    return isDbNull ? DBNull.Value : (object) val;
}

тогда вы можете использовать этот краткий код:

planIndexParameter.Value = AgeItem.AgeIndex.GetDBNullOrValue();

попробуйте это:

if (AgeItem.AgeIndex != null)
{
   SqlParameter[] parameters = new SqlParameter[1];
   SqlParameter planIndexParameter = new SqlParameter("@AgeIndex", SqlDbType.Int);
   planIndexParameter.Value = AgeItem.AgeIndex;
   parameters[0] = planIndexParameter;
}

другими словами, если параметр равен null, просто не отправляйте его в сохраненный proc (предполагая, конечно, что сохраненный proc принимает нулевые параметры, которые неявно присутствуют в вашем вопросе).


попробуйте что-то вроде этого:

if (_id_categoria_padre > 0)
{
    objComando.Parameters.Add("id_categoria_padre", SqlDbType.Int).Value = _id_categoria_padre;
}
else
{
    objComando.Parameters.Add("id_categoria_padre", DBNull.Value).Value = DBNull.Value;
}

int? nullableValue = null;
object nullableValueDB
{
   get{
       if(nullableValue==null)
          return DBNull.Value;
       else
          return (int)nullableValue;
   }
}

Я решаю так.


if (_id_categoria_padre > 0)
{
    objComando.Parameters.Add("id_categoria_padre", SqlDbType.Int).Value = _id_categoria_padre;
}
else
{
    objComando.Parameters.Add("id_categoria_padre", DBNull.Value).Value = DBNull.Value;
}

if (AgeItem.AgeIndex== null)  
    cmd.Parameters.Add(new SqlParameter("ParaMeterName", SqlDbType.DateTime).Value = DBNull);  
else  
    cmd.Parameters.Add(new SqlParameter("ParaMeterName", SqlDbType.DateTime).Value = AgeItem.AgeIndex);

Это то, что я делаю...

        var PhoneParam = new SqlParameter("@Phone", DBNull.Value);
        if (user.User_Info_Phone != null)
        {
            PhoneParam.SqlValue = user.User_Info_Phone;
        }

        return this.Database.SqlQuery<CustLogonDM>("UpdateUserInfo @UserName, @NameLast, @NameMiddle, @NameFirst, @Address, @City, @State, @PostalCode, @Phone",
            UserNameParam, NameLastParam, NameMiddleParam, NameFirstParam, AddressParam, CityParam, StateParam, PostalParam, PhoneParam).Single();

            dynamic psd = DBNull.Value;

            if (schedule.pushScheduleDate > DateTime.MinValue)
            {
                psd = schedule.pushScheduleDate;
            }


            sql.DBController.RunGeneralStoredProcedureNonQuery("SchedulePush",
                     new string[] { "@PushScheduleDate"},
                     new object[] { psd }, 10, "PushCenter");

простой метод расширения для этого могут быть:

    public static void AddParameter(this SqlCommand sqlCommand, string parameterName, 
        SqlDbType sqlDbType, object item)
    {
        sqlCommand.Parameters.Add(parameterName, sqlDbType).Value = item ?? DBNull.Value;
    }

что-нибудь не так с просто создать параметр "nullable"?

    public SqlParameter GetNullableParameter(string parameterName, object value)
    {
        if (value == null)
        {
            return new SqlParameter(parameterName, value);
        }
        else
        {
            return new SqlParameter(parameterName, DBNull.Value);
        }
    }