Eccezione quando il parametro AddWithValue è NULL

Ho il seguente codice per specificare i parametri per la query SQL. Ottengo seguente eccezione quando uso il Code 1 ; ma funziona bene quando uso il Code 2 . Nel Code 2 abbiamo un blocco per null e quindi un blocco if..else .

Eccezione:

La query con parametri ‘(@application_ex_id nvarchar (4000)) SELECT E.application_ex_id A’ si aspetta il parametro ‘@application_ex_id’, che non è stato fornito.

Codice 1 :

 command.Parameters.AddWithValue("@application_ex_id", logSearch.LogID); 

Codice 2 :

 if (logSearch.LogID != null) { command.Parameters.AddWithValue("@application_ex_id", logSearch.LogID); } else { command.Parameters.AddWithValue("@application_ex_id", DBNull.Value ); } 

DOMANDA

  1. Puoi spiegare perché non è in grado di prendere NULL dal valore logSearch.LogID nel Codice 1 (ma in grado di accettare DBNull)?

  2. C’è un codice migliore per gestire questo?

Riferimento :

  1. Assegna null a SqlParameter
  2. Il tipo di dati restituito varia in base ai dati nella tabella
  3. Errore di conversione dal database smallint in C # nullable int
  4. Qual è il punto di DBNull?

CODICE

  public Collection GetLogs(LogSearch logSearch) { Collection logs = new Collection(); 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 entityList = new Collection(); entityList.Add(new Log()); ArrayList records = EntityDataMappingHelper.SelectRecords(entityList, reader); for (int i = 0; i < records.Count; i++) { Log log = new Log(); Dictionary currentRecord = (Dictionary)records[i]; EntityDataMappingHelper.FillEntityFromRecord(log, currentRecord); logs.Add(log); } } //reader.Close(); } } } return logs; } 

Fastidioso, non è vero?

Puoi usare:

 command.Parameters.AddWithValue("@application_ex_id", ((object)logSearch.LogID) ?? DBNull.Value); 

In alternativa, usa uno strumento come “dapper”, che farà tutto ciò che ti incasina.

Per esempio:

 var data = conn.Query(commandText, new { application_ex_id = logSearch.LogID }).ToList(); 

Sono tentato di aggiungere un metodo a dapper per ottenere IDataReader … non sono ancora sicuro se sia una buona idea.

Trovo più semplice scrivere semplicemente un metodo di estensione per SqlParameterCollection che gestisce valori nulli:

 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); } 

Allora lo chiami come:

 sqlCommand.Parameters.AddWithNullableValue(key, value); 

Nel caso lo stiate facendo mentre chiamate una stored procedure: penso che sia più facile da leggere se dichiarate un valore predefinito sul parametro e aggiungetelo solo quando necessario.

Ad esempio: (sql)

 DECLARE PROCEDURE myprocedure @myparameter [int] = NULL AS BEGIN 

(C #)

 int? myvalue = initMyValue(); if (myvalue.hasValue) cmd.Parameters.AddWithValue("myparamater", myvalue); 

So che questo è vecchio, ma trovo questo utile e volevo condividere.

qualche problema, permesso con Necessariamente impostato SQLDbType

 command.Parameters.Add("@Name", SqlDbType.NVarChar); command.Parameters.Value=DBNull.Value 

dove SqlDbType.NVarChar digiti. Necessariamente impostare il tipo SQL. Enjou

Crea una class statica come questa:

 public static class Extensions { public static string RemoveNulls(this string container) { if (container == null) container = ""; return container; } } 

Quindi nel tuo codice, fai questo:

 Parameters.AddWithValue(sName, Value.RemoveNulls()); 

Questo è a prova di proiettile e molto facile da usare