c# - programming - ¿Cómo parametrizo una cadena nula con DBNull.Value de forma clara y rápida?
convention variable c# (8)
Me cansé de escribir el siguiente código:
/* Commenting out irrelevant parts
public string MiddleName;
public void Save(){
SqlCommand = new SqlCommand();
// blah blah...boring INSERT statement with params etc go here. */
if(MiddleName==null){
myCmd.Parameters.Add("@MiddleName", DBNull.Value);
}
else{
myCmd.Parameters.Add("@MiddleName", MiddleName);
}
/*
// more boring code to save to DB.
}*/
Entonces, escribí esto:
public static object DBNullValueorStringIfNotNull(string value)
{
object o;
if (value == null)
{
o = DBNull.Value;
}
else
{
o = value;
}
return o;
}
// which would be called like:
myCmd.Parameters.Add("@MiddleName", DBNullValueorStringIfNotNull(MiddleName));
Si esta es una buena manera de hacerlo, ¿qué sugeriría como nombre del método? DBNullValueorStringIfNotNull es un poco detallado y confuso.
También estoy abierto a formas de aliviar este problema por completo. Me encantaría hacer esto:
myCmd.Parameters.Add("@MiddleName", MiddleName==null ? DBNull.Value : MiddleName);
pero eso no va a funcionar porque el "Operador" ?? no se puede aplicar a operandos de tipo ''cadena'' y ''System.DBNull'' ".
Tengo a mi disposición C # 3.5 y SQL Server 2005 si me importa.
@David Gracias por tu sugerencia. El siguiente método funciona muy bien!
MiddleName ?? (object)DBNull.Value
Emite cualquiera de sus valores al object
y se compilará.
myCmd.Parameters.Add("@MiddleName", MiddleName==null ? (object)DBNull.Value : MiddleName);
Personalmente, esto es lo que haría con un método de extensión (asegúrese de que entra en una clase estática)
public static object GetStringOrDBNull(this string obj)
{
return string.IsNullOrEmpty(obj) ? DBNull.Value : (object) obj
}
Entonces tendrías
myCmd.Parameters.Add("@MiddleName", MiddleName.GetStringOrDBNull());
Prefiero darte dos sugerencias totalmente diferentes:
Utilice un ORM. Hay muchas herramientas ORM no intrusivas.
Escriba su propio envoltorio para construir comandos, con una interfaz más limpia. Algo como:
public class MyCommandRunner { private SqlCommand cmd; public MyCommandRunner(string commandText) { cmd = new SqlCommand(commandText); } public void AddParameter(string name, string value) { if (value == null) cmd.Parameters.Add(name, DBNull.Value); else cmd.Parameters.Add(name, value); } // ... more AddParameter overloads }
Si cambia el nombre de sus métodos AddParameter
a solo Add
, puede usarlo de una manera muy elegante:
var cmd = new MyCommand("INSERT ...")
{
{ "@Param1", null },
{ "@Param2", p2 }
};
Puede evitar la SqlString.Null
explícita al object
utilizando SqlString.Null
lugar de DBNull.Value
:
MiddleName ?? SqlString.Null
Hay tipos correspondientes para int, datetime, etc. Aquí hay un fragmento de código con un par de ejemplos más:
cmd.Parameters.AddWithValue("@StartDate", StartDate ?? SqlDateTime.Null);
cmd.Parameters.AddWithValue("@EndDate", EndDate ?? SqlDateTime.Null);
cmd.Parameters.AddWithValue("@Month", Month ?? SqlInt16.Null);
cmd.Parameters.AddWithValue("@FormatID", FormatID ?? SqlInt32.Null);
cmd.Parameters.AddWithValue("@Email", Email ?? SqlString.Null);
cmd.Parameters.AddWithValue("@ZIP", ZIP ?? SqlBoolean.Null);
Sí, a todos nos encantaría hacer myCmd.Parameters.Add("@MiddleName", MiddleName ?? DBNull.Value);
. O mejor aún, haga que la capa SqlClient freakin ''entienda que CLR null
debe asignarse a DBNull.Value
al agregar un parámetro. Desafortunadamente, el sistema de tipo .Net cierra la primera alternativa y la implementación de SqlClient cierra la segunda.
Iría con un nombre de función bien conocido, como Coalesce o IsNull . Cualquier desarrollador de bases de datos reconocerá lo que hace en un instante, solo con el nombre.
Yo sugeriría usar propiedades anulables en lugar de campos públicos y un método ''AddParameter'' (no sé si este código está optimizado o es correcto, solo en la parte superior de mi cabeza):
private string m_MiddleName;
public string MiddleName
{
get { return m_MiddleName; }
set { m_MiddleName = value; }
}
.
.
.
public static void AddParameter(SQLCommand cmd, string parameterName, SQLDataType dataType, object value)
{
SQLParameter param = cmd.Parameters.Add(parameterName, dataType);
if (value is string) { // include other non-nullable datatypes
if (value == null) {
param.value = DBNull.Value;
} else {
param.value = value;
}
} else {
// nullable data types
// UPDATE: HasValue is for nullable, not object type
if (value.HasValue) // {{{=====================================================
{
param.value = value;
} else
{
param.value = DBNull.Value;
}
}
}
.
.
.
AddParameter(cmd, "@MiddleName", SqlDbType.VarChar, MiddleName);
myCmd.Parameters.Add("@MiddleName", MiddleName ?? (object)DBNull.Value);