2017-11-10 6 views
2

Ich habe eine Funktion, in der ich zwei Anfragen an eine SQL Server-Datenbank senden; Bei der zweiten Anfrage bekomme ich jedoch eine SqlException und den Parameter @mpe fehlt. Wenn ich versuche, den Konstantenwert 0 im Konstruktor SqlParameter zu setzen.SqlParameter (String, Objekt) kann nicht mit konstanten Wert umgehen

protected static string GetX(int mpe, string xsection, string xkey) 
    { 
     var xSetup = App.Current.Db.GetType<Data.CachedTypes.XSetup>(
      "where [email protected] and [email protected] and [email protected]", 
      new System.Data.SqlClient.SqlParameter("@mpe", mpe), 
      new System.Data.SqlClient.SqlParameter("@xsection", xsection), 
      new System.Data.SqlClient.SqlParameter("@xkey", xkey)); 

     if (mpe > 0 && xSetup == null) 
     { 
      // Fallback mechanism. Always tries to get the default for all MPEs. 
      xSetup = App.Current.Db.GetType<Data.CachedTypes.XSetup>(
       "where [email protected] and [email protected] and [email protected]", 
       new System.Data.SqlClient.SqlParameter("@mpe", 0), <-- THIS FAILES!! 
       new System.Data.SqlClient.SqlParameter("@xsection", xsection), 
       new System.Data.SqlClient.SqlParameter("@xkey", xkey)); 

Wenn ich jedoch den konstanten Wert 0 auf einen lokalen Wert int xmpe = 0 und übergeben diese an den Konstruktor extrahieren, führt die SQL-Abfrage wie erwartet und ein Ergebnis abgerufen wird. Kann jemand erklären, warum das passiert?

Antwort

3

Das liegt daran, wenn Sie dies tun:

new System.Data.SqlClient.SqlParameter("@mpe", 0) 

Der folgende Konstruktor verwendet wird:

public SqlParameter(string parameterName, SqlDbType dbType) 

, die gleich ist:

new System.Data.SqlClient.SqlParameter("@mpe", SqlDbType.BigInt); 

Das liegt daran, 0 bis implizit konvertierbar ist jeder Enum-Typ, so ist diese Überladung gegenüber diesem bevorzugt:

public SqlParameter(string parameterName, object value) 

Allerdings, wenn Sie

int someInt = 0; // or anything else 
new System.Data.SqlClient.SqlParameter("@mpe", someInt) 

Willkürliche int tun, ist nicht implizit konvertierbar Enum (einzige Konstante 0 ist), so richtig Überlastung gewählt wird (mit object value). Die Tatsache, dass ein beliebiges int auch 0 sein kann, spielt keine Rolle, da die Überladungsauflösung zur Kompilierungszeit durchgeführt wird. Wenn Sie jedoch tun:

const int mpe = 0; 
new System.Data.SqlClient.SqlParameter("@mpe", mpe); 

Dann wieder falsch Konstruktor gewählt, weil mpe bekannt ist 0 bei der Kompilierung zu sein. Wenn Sie dies tun:

const int mpe = 1; 
new System.Data.SqlClient.SqlParameter("@mpe", mpe); 

Dann wieder object value gewählt wird, für den oben genannten Gründen.

Um eine korrekte Überlastung die ganze Zeit zu erzwingen, werft eure 0 Objekt zu:

new System.Data.SqlClient.SqlParameter("@mpe", (object) 0); 
+0

Das ist es, 'neue SqlParameter ("name", (Objekt) 0)' wird bei erwarteten Verhalten zu arbeiten. –

Verwandte Themen