net - sqlparameter output c#
¿Por qué el constructor de nombre/valor de SqlParameter trata a 0 como nulo? (2)
Observé un problema extraño en un fragmento de código en el que una consulta de SQL adhoc no producía el resultado esperado, a pesar de que sus parámetros coincidían con los registros en la fuente de datos. Decidí ingresar la siguiente expresión de prueba en la ventana inmediata:
new SqlParameter("Test", 0).Value
Esto dio un resultado de null
, lo que me deja rascándome la cabeza. Parece que el constructor SqlParameter
trata los ceros como nulos. El siguiente código produce el resultado correcto:
SqlParameter testParam = new SqlParameter();
testParam.ParameterName = "Test";
testParam.Value = 0;
// subsequent inspection shows that the Value property is still 0
¿Alguien puede explicar este comportamiento? ¿Es de alguna manera intencional? Si es así, es potencialmente peligroso ...
Como se indica en la documentation de ese constructor:
Cuando especifica un Objeto en el parámetro de valor, el SqlDbType se deduce del tipo de Microsoft .NET Framework del Objeto.
Tenga cuidado cuando use esta sobrecarga del constructor SqlParameter para especificar valores de parámetros enteros. Debido a que esta sobrecarga toma un valor de tipo Object , debe convertir el valor integral en un Tipo de Object cuando el valor sea cero, como lo demuestra el siguiente ejemplo de C #.
Parameter = new SqlParameter("@pname", (object)0);
Si no realiza esta conversión, el compilador asume que está intentando llamar a la sobrecarga del constructor SqlParameter (string, SqlDbType) .
Simplemente llamabas a un constructor diferente de lo que pensabas en tu caso.
La razón de esto es que C # permite una conversión implícita del literal 0
entero a los tipos de enumeración (que son solo tipos integrales debajo), y esta conversión implícita hace que el constructor (string, SqlDbType)
sea una mejor coincidencia para la resolución de sobrecarga que el conversión de boxeo necesaria para convertir int
en object
para el constructor (string, object)
.
Esto nunca será un problema cuando pase una variable int
, incluso si el valor de esa variable es 0
(porque no es un literal cero), o cualquier otra expresión que tenga el tipo int
. Tampoco sucederá si explícitamente convierte el int
a object
como se vio anteriormente, porque entonces solo hay una sobrecarga coincidente.
Es una buena práctica usar datos escritos al pasar / agregar sus parámetros.
A continuación puede realizar la tarea de la siguiente manera:
Para datos escritos de cadena / varchar:
SqlParameter pVarchar = new SqlParameter
{
ParameterName = "Test",
SqlDbType = System.Data.SqlDbType.VarChar,
Value = string.Empty,
};
Para datos introducidos int:
SqlParameter pInt = new SqlParameter
{
ParameterName = "Test",
SqlDbType = System.Data.SqlDbType.Int,
Value = 0,
};
Puede cambiar el valor de SqlDbType
acuerdo con los datos utilizados.