Atribuir null a um SqlParameter

O código a seguir dá um erro – “Nenhuma conversão implícita do DBnull para 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; 

O problema é que o operador ?: pode determinar o tipo de retorno porque você está retornando um valor int ou um valor de tipo DBNull, que não são compatíveis.

É claro que você pode converter a ocorrência de AgeIndex em object tipo, o que satisfaria o requisito ?: .

Você pode usar o ?? Operador de coalescência nula da seguinte forma

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

Aqui está uma citação da documentação do MSDN para o operador ?: Que explica o problema

O tipo de first_expression e second_expression deve ser o mesmo ou uma conversão implícita deve existir de um tipo para o outro.

A resposta aceita sugere o uso de um casting. No entanto, a maioria dos tipos SQL possui um campo Null especial que pode ser usado para evitar essa conversão.

Por exemplo, SqlInt32.Null “Representa um DBNull que pode ser atribuído a essa instância da class SqlInt32.”

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

Você precisa passar DBNull.Value como um parâmetro nulo no SQLCommand, a menos que um valor padrão seja especificado no procedimento armazenado (se você estiver usando o procedimento armazenado). A melhor abordagem é atribuir DBNull.Value para qualquer parâmetro ausente antes da execução da consulta, e seguir foreach fará o trabalho.

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

Caso contrário, altere esta linha:

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

Do seguinte modo:

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

Porque você não pode usar diferentes tipos de valores na declaração condicional, como DBNull e int são diferentes uns dos outros. Espero que isso ajude.

Com uma linha de código, tente isto:

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

Tente isto:

 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; 

Na minha opinião, a melhor maneira é fazer isso com a propriedade Parameters da class SqlCommand :

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

Considere o uso da estrutura Nullable (T) disponível. Ele permitirá que você defina apenas valores, se você os tiver, e seus objects de Comando SQL reconhecerão o valor anulável e serão processados ​​de acordo, sem problemas em seu fim.

Se você usar o operador condicional (ternário), o compilador precisará de uma conversão implícita entre os dois tipos, caso contrário, você obterá uma exceção.

Então você pode consertá-lo, lançando um dos dois para System.Object :

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

Mas como o resultado não é muito bonito e você sempre precisa se lembrar desse casting, você pode usar esse método de extensão:

 public static object GetDBNullOrValue(this T val) { bool isDbNull = true; Type t = typeof(T); if (Nullable.GetUnderlyingType(t) != null) isDbNull = EqualityComparer.Default.Equals(default(T), val); else if (t.IsValueType) isDbNull = false; else isDbNull = val == null; return isDbNull ? DBNull.Value : (object) val; } 

Então você pode usar este código conciso:

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

Tente isto:

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

Em outras palavras, se o parâmetro for nulo, não o envie para o seu procedimento armazenado (supondo, é claro, que o procedimento armazenado aceite parâmetros nulos implícitos em sua pergunta).

tente algo como isto:

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

Estou resolvendo assim.

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

Isso é o que eu simplesmente faço …

  var PhoneParam = new SqlParameter("@Phone", DBNull.Value); if (user.User_Info_Phone != null) { PhoneParam.SqlValue = user.User_Info_Phone; } return this.Database.SqlQuery("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"); 

Um método de extensão simples para isso seria:

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

Qualquer coisa errada com simplesmente criar parâmetro “anulável” fazer?

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