2009-03-06 10 views
6

Hubo preguntas similares pero las respuestas no fueron las que estaba buscando. Quiero insertar el valor de NULL en la base de datos de SQL Server si la referencia es NULL o aún no se ha asignado un valor. Por el momento estoy probando para nula y parece que.Net insertando valores NULL en la base de datos de SQL Server a partir de valores variables

String testString = null; 

if (testString == null) 
{ 
    command.Parameters.AddParameter(new SqlParameter("@column", DBNull.Value); 
} 
else 
{ 
    command.Parameters.AddParameter(new SqlParameter("@column", testString); 
} 

Esto se ve y se siente muy torpe para mí. Tengo bastantes valores que estoy insertando en una base de datos y para probarlos todos como el anterior es muy detallado. ¿.Net no maneja esto de alguna manera? Pensé que tal vez si usaba cadena en lugar de Cadena, pero eso tampoco parece funcionar. Al mirar alrededor encontré artículos que hablan sobre el uso de tipos Nullable.

System.Nullable<T> variable 

Esto parece funcionar para primitivos, int ?, char? ¿doble? y bool ?. Entonces eso podría funcionar para ellos, pero ¿qué pasa con las cuerdas? Me estoy perdiendo de algo. ¿Qué tipos debo usar para valores primitivos y para valores de cadena para no tener que probar valores repetidamente antes de insertarlos?

EDITAR: Antes de obtener demasiadas respuestas sobre los operadores ternarios. Me gustan pero no en este contexto. No tiene sentido para mí tener que probar ese valor y tener toda esa lógica extra, cuando ese tipo de cosas podría haberse implementado más abajo en .Net Framework y si supiera qué tipo dar, lo conseguiría. gratis.

Edit: Bien, entonces muchachos me ayudan a formular mi plan de ataque. Usaré Nullable para mis primitivos (int ?, double? Etc) y para mis Strings usaré String pero el ?? prueba. Esto mantiene las cosas menos detalladas. ¿Hay algo que me falta aquí, como perder algo de semántica?

Respuesta

11

Incluso mejor que el ternario es el operador de doble signo de interrogación (??). Toma el primer valor no nulo.Por lo tanto:

string x = null; 
command.Parameters.AddParameter(
    new SqlParameter("@column", (object)x ?? DBNull.Value); 

le daría un Parm con un valor de DBNull.Value, pero

string x = "A String"; 
command.Parameters.AddParameter(
    new SqlParameter("@column", (object)x ?? DBNull.Value); 

le daría a un Parm con "una cadena" como valor.

+1

El compilador se ahogará con esto porque no puede convertir implícitamente de cadena a DBNull. – LukeH

+0

Tiene razón. Necesita bajar la cadena (x) a un objeto. Ejemplo editado. –

+0

No es un fan de esto, porque hace que sea fácil para .Net adivinar el tipo incorrecto para un parámetro. Sería mejor especificar el tipo de parámetro a través de una sobrecarga que solicita una enumeración 'SqlDbType'. –

0

Tal vez el operador ternario es algo que puede serle útil.

0

Lo hago a veces, es la siguiente:

command.Parameters.Add ("@column", SqlDbType.VarChar).Value = DBNull.Value; 

if(String.IsNullOrEmpty (theString) == false) 
{ 
    command.Parameters["@column"].Value = theString; 
} 
3

anulable funciona muy bien para las primitivas. Voy a tener que probar el comportamiento de la cadena, pero una opción para al menos limpiar tu código sería definir un método de extensión de cadena.

Puede usar el ?? operador de cadenas:

command.Parameters.AddParameter (nueva SqlParameter ("columna @", myNull ?? (objeto) DBNull.Value);

?? devuelve el primer elemento si no es nulo, otra en cuanto a que devuelve el segundo elemento.

Editar

solucionado el código anterior por lo que se compilará, es necesario especificar DBNull.Value a un objeto.

+0

El compilador se ahogará con esto porque no puede convertir implícitamente de cadena a DBNull. – LukeH

+0

Creo que puedes usar testString ?? (cadena) DBNull.Value. –

+0

¿Qué tal ((objeto) testString) ?? DBNull.Vale – recursive

0

Estoy de acuerdo que es torpe y un poco lamentable que SqlParameter.Value debe establecerse en DbNull.Value. Pero hay No hay forma de evitarlo, así que tienes que vivir probando null.

0

Nullable<T> no se puede aplicar a String ya que es un tipo de referencia y no un tipo de valor.

+0

Hola. Solo lo busqué, es decepcionante que la cadena en oposición a la cadena siga siendo un tipo de referencia. Aparentemente es un alias pero luego, por ejemplo, string a = "hello"; cadena b = "h"; b + = "ello"; entonces a == b devuelve verdadero porque compara sus valores. Interesante. – uriDium

+0

Sí y No - Hay una buena razón por la cual la cuerda es un tipo de referencia y no un tipo de valor (mira algunas de las cosas de Jon Skeet, él es un profesional en esa área); Para los casos que ha especificado, es por eso que crearon la clase StringBuilder. –

0

Ejemplo:

if (txtDisplayName.Text != "") 
{ 
    insert into table (id,display_name) values ('" + txtID.Text + "','" + txtDisplayName.Text + "'); 
} 
else 
{ 
    insert into table (id) values ('" + txtID.Text + "'); 
} 

Esto insertará null.

+0

Hola, bienvenido a Stack Overflow! Este es un fragmento de código incompleto. – Jesse

Cuestiones relacionadas