c# - operator - Asignar null a un SqlParameter
parameters addwithvalue null (17)
¿Algo malo con simplemente crear el parámetro "nullable" do?
public SqlParameter GetNullableParameter(string parameterName, object value)
{
if (value == null)
{
return new SqlParameter(parameterName, value);
}
else
{
return new SqlParameter(parameterName, DBNull.Value);
}
}
El siguiente código muestra un error: "Sin conversión implícita de DBnull a 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;
Con una línea de código, intente esto:
var piParameter = new SqlParameter("@AgeIndex", AgeItem.AgeIndex ?? (object)DBNull.Value);
Considere usar la estructura Nullable (T) disponible. Solo te permitirá establecer valores si los tienes, y tus objetos de Comando de SQL reconocerán el valor que admite valores NULL y lo procesará como corresponda sin problemas.
El problema es que el operador ?:
No puede determinar el tipo de devolución porque devuelve un valor int
o un valor de tipo DBNull, que no son compatibles.
Por supuesto, puede convertir la instancia de AgeIndex en un tipo de object
que satisfaga el requisito ?:
Puedes usar el ??
operador nulo-coalescente de la siguiente manera
SqlParameter[] parameters = new SqlParameter[1];
SqlParameter planIndexParameter = new SqlParameter("@AgeIndex", SqlDbType.Int);
planIndexParameter.Value = (object)AgeItem.AgeIndex ?? DBNull.Value;
parameters[0] = planIndexParameter;
Aquí hay una cita de la documentación de MSDN para el operador ?:
Que explica el problema
El tipo de first_expression y second_expression debe ser el mismo o debe existir una conversión implícita de un tipo a otro.
En mi opinión, la mejor manera es hacer esto con la propiedad Parameters de la clase SqlCommand :
public static void AddCommandParameter(SqlCommand myCommand)
{
myCommand.Parameters.AddWithValue(
"@AgeIndex",
(AgeItem.AgeIndex== null) ? DBNull.Value : AgeItem.AgeIndex);
}
Esto es lo que hago ...
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();
Necesita pasar DBNull.Value como un parámetro nulo dentro de SQLCommand, a menos que se especifique un valor predeterminado dentro del procedimiento almacenado (si está utilizando un procedimiento almacenado). El mejor enfoque es asignar DBNull.Value para cualquier parámetro faltante antes de la ejecución de la consulta, y seguir a foreach hará el trabajo.
foreach (SqlParameter parameter in sqlCmd.Parameters)
{
if (parameter.Value == null)
{
parameter.Value = DBNull.Value;
}
}
De lo contrario, cambie esta línea:
planIndexParameter.Value = (AgeItem.AgeIndex== null) ? DBNull.Value : AgeItem.AgeIndex;
Como sigue:
if (AgeItem.AgeIndex== null)
planIndexParameter.Value = DBNull.Value;
else
planIndexParameter.Value = AgeItem.AgeIndex;
Porque no puede usar diferentes tipos de valores en la declaración condicional, ya que DBNull e int son diferentes entre sí. Espero que esto ayude
Prueba esto:
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;
Prueba esto:
if (AgeItem.AgeIndex != null)
{
SqlParameter[] parameters = new SqlParameter[1];
SqlParameter planIndexParameter = new SqlParameter("@AgeIndex", SqlDbType.Int);
planIndexParameter.Value = AgeItem.AgeIndex;
parameters[0] = planIndexParameter;
}
En otras palabras, si el parámetro es nulo simplemente no lo envíe a su proceso almacenado (suponiendo, por supuesto, que el proceso almacenado acepte parámetros nulos que están implícitos en su pregunta).
Si usa el operador condicional (ternario), el compilador necesita una conversión implícita entre ambos tipos; de lo contrario, obtendrá una excepción.
Para que pueda solucionarlo lanzando uno de los dos a System.Object
:
planIndexParameter.Value = (AgeItem.AgeIndex== null) ? DBNull.Value : (object) AgeItem.AgeIndex;
Pero dado que el resultado no es muy bonito y siempre debes recordar este lanzamiento, podrías utilizar dicho método de extensión en su lugar:
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;
}
Entonces puedes usar este código conciso:
planIndexParameter.Value = AgeItem.AgeIndex.GetDBNullOrValue();
Un método de extensión simple para esto sería:
public static void AddParameter(this SqlCommand sqlCommand, string parameterName,
SqlDbType sqlDbType, object item)
{
sqlCommand.Parameters.Add(parameterName, sqlDbType).Value = item ?? DBNull.Value;
}
intente algo como esto:
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;
}
La respuesta aceptada sugiere hacer uso de un elenco. Sin embargo, la mayoría de los tipos de SQL tienen un campo nulo especial que se puede usar para evitar este reparto.
Por ejemplo, SqlInt32.Null
"Representa un DBNull que se puede asignar a esta instancia de la clase SqlInt32".
int? example = null;
object exampleCast = (object) example ?? DBNull.Value;
object exampleNoCast = example ?? SqlInt32.Null;
dynamic psd = DBNull.Value;
if (schedule.pushScheduleDate > DateTime.MinValue)
{
psd = schedule.pushScheduleDate;
}
sql.DBController.RunGeneralStoredProcedureNonQuery("SchedulePush",
new string[] { "@PushScheduleDate"},
new object[] { psd }, 10, "PushCenter");
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);
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;
}
}
Estoy resolviendo así.