2012-11-19 1 views
55

Ich habe folgenden Code zum Angeben von Parametern für die SQL-Abfrage. Ich bekomme folgende Ausnahme, wenn ich Code 1 verwende; aber funktioniert gut, wenn ich Code 2 verwende. In Code 2 haben wir einen Check für null und damit einen if..else Block.Ausnahme, wenn der Parameter AddWithValue NULL ist

Ausnahme:

Die parametrisierte Abfrage '(@application_ex_id nvarchar (4000)) SELECT E.application_ex_id A' erwartet, dass der Parameter '@application_ex_id', die nicht zugeführt wurde.

Code 1:

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

Code 2:

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

FRAGE

  1. Können Sie bitte erläutern, warum NULL nicht vom logSearch.LogID-Wert in Code 1 akzeptiert werden kann (aber DBNull akzeptieren kann)?

  2. Gibt es einen besseren Code, um damit umzugehen?

Referenz:

  1. Assign null to a SqlParameter
  2. Datatype returned varies based on data in table
  3. Conversion error from database smallint into C# nullable int
  4. What is the point of DBNull?

CODE

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; 
    } 
+3

verwenden Was meinen Sie besser? Code 2 ist die richtige Methode, um einen Nullwert an eine Datenbank zu senden. –

+0

Referenz: http://stackoverflow.com/questions/13265704/conversion-error-from-database-smallint-into-c-sharp-nullable-int – Lijo

Antwort

84

Ärgerlich, nicht wahr? verwenden

können Sie:

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

Oder alternativ, verwenden Sie ein Tool wie „adrett“, die alles, was für Sie durcheinander tun.

Zum Beispiel:

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

Ich bin versucht, ein Verfahren in dem Dapper die IDataReader zu bekommen ... nicht wirklich sicher noch, ob es eine gute Idee ist.

+0

@Phil tatsächlich; Die meisten Dinge können ... aber ich mag es nicht, Erweiterungsmethoden auf 'Objekt' hinzuzufügen, und wir können nicht sehen, ob das' Nullable 'vs' String', etc ... aber ja: es könnte leicht getan werden genug. –

+1

Ich dachte an eine Erweiterung der Eigenschaft 'Parameters' - ist das ein' Objekt'? –

+3

@Phil hmmm, ja es ist, und ich sehe was du meinst ... vielleicht 'AddWithValueAndTreatNullTheRightDamnedWay (...)' –

1

ein Problem, erlaubt mit Notwendigerweise gesetzt SqlDbType

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

wo SqlDbType.NVarChar Sie eingeben. Stellen Sie den SQL-Typ zwingend ein. Enjou

34

Ich finde es einfacher, nur eine Erweiterungsmethode für die SqlParameterCollection zu schreiben, die Nullwerte behandelt:

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

Dann Sie es genau wie nennen: Sie

sqlCommand.Parameters.AddWithNullableValue(key, value); 
+0

_value_ kann ** int oder int ?, string, bool oder bool ?, DateTime oder Datetime? ** usw. sein? – Kiquenet

+0

@Kiquenet Ja ... – AxiomaticNexus

+2

Ich las Marcs Antwort und dachte: "Ich denke, ich schreibe lieber eine Erweiterungsmethode für die Parametersammlung", dann scrollte ich ein Haar runter ... (Das Schöne an einer Erweiterungsmethode ist das Ich kann eine einzelne Suche/ersetzen nach und alle meine Code-Updates sind fertig) – jleach

2

Nur für den Fall‘ Das tun Sie, während Sie eine gespeicherte Prozedur aufrufen: Ich denke, es ist einfacher zu lesen, wenn Sie einen Standardwert für den Parameter deklarieren und ihn nur bei Bedarf hinzufügen.

Zum Beispiel: (SQL)

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

(C#)

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

Ich weiß, das alt ist, aber ich finde diese nützlich und wollte teilen.

-3

Erstellen Sie eine statische Klasse wie folgt:

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

Dann in Ihrem Code, dies zu tun:

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

Dies ist kugelsicher und sehr einfach

+1

Dies wird "" und nicht null ... – Lars

+0

Das ist was er will - nicht um eine Null einzugeben – TheWizardOfTN