Tengo el siguiente código para especificar parámetros para la consulta SQL. Recibo la siguiente excepción cuando uso Code 1
; pero funciona bien cuando lo uso Code 2
. En Code 2
tenemos una comprobación de nulo y, por tanto, un if..else
bloque.
Excepción:
La consulta parametrizada '(@application_ex_id nvarchar (4000)) SELECT E.application_ex_id A' espera el parámetro '@application_ex_id', que no se proporcionó.
Codigo 1 :
command.Parameters.AddWithValue("@application_ex_id", logSearch.LogID);
Codigo 2 :
if (logSearch.LogID != null)
{
command.Parameters.AddWithValue("@application_ex_id", logSearch.LogID);
}
else
{
command.Parameters.AddWithValue("@application_ex_id", DBNull.Value );
}
PREGUNTA
¿Puede explicar por qué no puede tomar NULL del valor logSearch.LogID en el Código 1 (pero puede aceptar DBNull)?
¿Existe un código mejor para manejar esto?
Referencia :
- Asignar nulo a un parámetro Sql
- El tipo de datos devuelto varía según los datos de la tabla
- Error de conversión de la base de datos smallint a C # nullable int
- ¿Cuál es el punto de DBNull?
CÓDIGO
public Collection<Log> GetLogs(LogSearch logSearch)
{
Collection<Log> logs = new Collection<Log>();
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
string commandText = @"SELECT *
FROM Application_Ex E
WHERE (E.application_ex_id = @application_ex_id OR @application_ex_id IS NULL)";
using (SqlCommand command = new SqlCommand(commandText, connection))
{
command.CommandType = System.Data.CommandType.Text;
//Parameter value setting
//command.Parameters.AddWithValue("@application_ex_id", logSearch.LogID);
if (logSearch.LogID != null)
{
command.Parameters.AddWithValue("@application_ex_id", logSearch.LogID);
}
else
{
command.Parameters.AddWithValue("@application_ex_id", DBNull.Value );
}
using (SqlDataReader reader = command.ExecuteReader())
{
if (reader.HasRows)
{
Collection<Object> entityList = new Collection<Object>();
entityList.Add(new Log());
ArrayList records = EntityDataMappingHelper.SelectRecords(entityList, reader);
for (int i = 0; i < records.Count; i++)
{
Log log = new Log();
Dictionary<string, object> currentRecord = (Dictionary<string, object>)records[i];
EntityDataMappingHelper.FillEntityFromRecord(log, currentRecord);
logs.Add(log);
}
}
//reader.Close();
}
}
}
return logs;
}
Respuestas:
Molesto, ¿no es así?
Puedes usar:
command.Parameters.AddWithValue("@application_ex_id", ((object)logSearch.LogID) ?? DBNull.Value);
O alternativamente, use una herramienta como "dapper", que hará todo ese lío por usted.
Por ejemplo:
var data = conn.Query<SomeType>(commandText, new { application_ex_id = logSearch.LogID }).ToList();
Estoy tentado de agregar un método a Dapper para obtener el
IDataReader
... aún no estoy seguro de si es una buena idea.fuente
Parameters
propiedad, ¿es esoObject
?AddWithValueAndTreatNullTheRightDamnedWay(...)
null
en un parámetro el valor significa "no enviar este parámetro". Sospecho que fue una mala decisión que simplemente se incorporó. De hecho, creo que la mayor parteDBNull
fue una decisión fundamentalmente mala que se preparóMe resulta más fácil escribir un método de extensión para el
SqlParameterCollection
que maneja valores nulos:public static SqlParameter AddWithNullableValue( this SqlParameterCollection collection, string parameterName, object value) { if(value == null) return collection.AddWithValue(parameterName, DBNull.Value); else return collection.AddWithValue(parameterName, value); }
Entonces simplemente lo llamas como:
sqlCommand.Parameters.AddWithNullableValue(key, value);
fuente
return collection.AddWithValue(parameterName, value ?? DBNull.Value);
En caso de que esté haciendo esto mientras llama a un procedimiento almacenado: creo que es más fácil de leer si declara un valor predeterminado en el parámetro y lo agrega solo cuando sea necesario.
SQL:
DECLARE PROCEDURE myprocedure @myparameter [int] = NULL AS BEGIN
C#:
int? myvalue = initMyValue(); if (myvalue.hasValue) cmd.Parameters.AddWithValue("myparamater", myvalue);
fuente
algún problema, permitido con necesariamente establecido SQLDbType
command.Parameters.Add("@Name", SqlDbType.NVarChar); command.Parameters.Value=DBNull.Value
donde escribe SqlDbType.NVarChar. Establecer necesariamente el tipo de SQL.
fuente