Was ist die beste Methode Parameter SQLCommand passieren?
-
08-07-2019 - |
Frage
Was ist die beste Methode Parameter SQLCommand passieren? Sie tun können:
cmd.Parameters.Add("@Name", SqlDbType.VarChar, 20).Value = "Bob";
oder
cmd.Parameters.Add("@Name", SqlDbType.VarChar).Value = "Bob";
oder
cmd.Parameters.Add("@Name").Value = "Bob";
Es scheint, wie der erste könnte man irgendwie „besser“ sein entweder Performance-weise oder Fehlerprüfung weisen. Aber ich möchte mehr definitiv wissen.
Lösung
Sie können auch AddWithValue()
verwenden, aber die Möglichkeit der falschen impliziten Typumwandlung bewusst sein.
cmd.Parameters.AddWithValue("@Name", "Bob");
Andere Tipps
Was geht da vor?
Sie zitieren die Parameterlisten für mehrere Überlastungen von Add
. Dies sind bequeme Methoden, die direkt an Konstruktorüberladungen für die SqlParameter
Klasse entsprechen. Sie bauen im Wesentlichen die Parameter-Objekt, was Konstruktor hat die gleiche Signatur wie die Bequemlichkeit Methode, die Sie genannt wird, und rufen Sie dann SqlParameterCollection.Add(SqlParameter)
wie folgt aus:
SqlParameter foo = new SqlParameter(parameterName, dbType, size);
this.Add(foo);
AddWithValue
ähnlich ist, jedoch nimmt Komfort noch weiter, auch den Wert einstellen. Allerdings war es tatsächlich einen Rahmen Fehler zu beheben eingeführt. Zu zitieren MSDN,
Die Überlastung von
Add
, die nimmt ein String und ein Objekt wurde als veraltet wegen der möglichen Zweideutigkeit mit derSqlParameterCollection.Add
Überlastung das dauertString
undSqlDbType
Enumerationswerts wo eine Weitergabe integer mit der Zeichenfolge könnte interpretiert als entweder die Parameterwert oder das entsprechendeSqlDbType
Wert. VerwendenAddWithValue
wann immer Sie wollen einen Parameter hinzufügen durch ihren Namen und Wert angeben.
Die Konstruktorüberladungen für die SqlParameter
Klasse ist nur Komfort zum Beispiel Eigenschaften festlegen. Sie verkürzen den Code, mit marginalen Einfluss auf die Leistung: der Konstruktor kann Setter-Methoden umgehen und direkt auf private Mitglieder arbeiten. Wenn es ein Unterschied ist wird es nicht viel sein.
Was soll ich tun?
Beachten Sie die folgende (von MSDN)
Für die bidirektionale und Ausgang Parameter und Rückgabewerte, Sie muss den Wert von
Size
gesetzt. Das ist nicht für Eingabeparameter erforderlich ist, und wenn nicht explizit festgelegt, ist der Wert von der tatsächlichen Größe der abgeleiteten angegebene Parameter, wenn ein parametrisierte Anweisung ausgeführt wird.
Der Standardtyp eingegeben wird. Wenn Sie jedoch die Größe zu entnehmen, wie dies zulassen und Sie recyceln das Parameter-Objekt in einer Schleife (Sie haben Sie gesagt mit Leistung betroffen sind), dann wird die Größe durch den ersten Wert und alle nachfolgenden Werte festgelegt werden, die länger werden abgeschnitten. Natürlich ist dies nur von Bedeutung für variable Längenwerte wie Strings.
Wenn Sie die gleichen logischen Parameter wiederholen in einer Schleife sind vorbei empfehle ich Ihnen, außerhalb der Schleife und Größe es in geeigneter Weise ein SqlParameter-Objekt zu erstellen. Überdimensionierung ein varchar ist harmlos, also wenn es ein PITA ist das genaue Maximum zu erhalten, ist es nur größer eingestellt, als Sie jemals die Spalte erwarten zu sein. Weil Sie das Objekt sind Recycling, anstatt eine neue für jede Iteration, Speicherverbrauch über die Dauer der Schleife zu schaffen wird wahrscheinlich fallen , auch wenn Sie ein bisschen aufgeregt mit dem Oversizing erhalten.
Die Wahrheit zu sagen, es sei denn, Sie Tausende von Anrufen verarbeiten, nichts davon wird viel Unterschied machen. AddWithValue
erstellt ein neues Objekt, das Sizing Problem ausweicht. Es ist kurz und süß und leicht zu verstehen. Wenn Sie eine Schleife durch Tausende, meinen Ansatz. Wenn Sie nicht, verwenden Sie AddWithValue
Ihren Code einfach zu halten und leicht zu pflegen.
2008 war vor langer Zeit
In den Jahren seit ich dies schrieb, hat sich die Welt verändert. Es gibt neue Arten von Datum, und es gibt auch ein Problem, das nicht meinen Kopf gehen, bis ein neues Problem mit Terminen mich über die Auswirkungen der Erweiterung denken ließ.
erweiternde und verjüngende, für diejenigen, die nicht mit den Bedingungen, sind Qualitäten von Datentypkonvertierungen. Wenn Sie einen int zu einem Doppel zuweisen, gibt es keinen Verlust an Präzision, da doppelt so hoch ist „breite“. Es ist immer sicher, dies zu tun, so Konvertierung erfolgt automatisch. Dies ist, warum Sie einen int zu einem Doppel zuordnen können, aber Sie in die andere Richtung haben eine explizite Umwandlung zu tun - doppelt auf eine Verengung Umwandlung mit potentiellem Verlust an Präzision int sind.
Dies kann auf Strings anwenden: NVARCHAR breiter als VARCHAR ist, so dass Sie ein VARCH zuweisenAR zu einem NVARCHAR aber in die andere Richtung erfordert eine Besetzung. Vergleich funktioniert, weil der VARCHAR erweitert implizit NVARCHAR, , aber dies wird durch die Verwendung von Indizes stören!
C # Strings sind Unicode, so AddWithValue wird ein NVARCHAR Parameter erzeugen. Am anderen Ende, erweitern VARCHAR Spaltenwerte NVARCHAR zum Vergleich. Dies schließt nicht die Abfrageausführung stoppen, aber es verhindert, dass Indizes verwendet werden. Das ist schlecht.
Was kann man dagegen tun? Sie haben zwei mögliche Lösungen.
- Explizit die Parameter eingeben. Das bedeutet, nicht mehr AddWithValue
- Ändern Sie alle String-Spalte Typen NVARCHAR.
Notwasserung VARCHAR ist wahrscheinlich die beste Idee. Es ist eine einfache Änderung mit vorhersehbaren Folgen und es verbessert die Lokalisierung Geschichte. Allerdings können Sie dies nicht als Option.
In diesen Tagen ich nicht viel direkten ADO.NET tun. Linq2Sql ist jetzt meine Waffe der Wahl, und die Handlung dieses Update des Schreibens verlassen hat mich gefragt, wie es dieses Problem umgeht. Ich habe ein plötzliches, brennendes Verlangen, meine Datenbanken von VARCHAR zu löschen.
Ich würde sagen, # 1 sicher. Aber wie Microsoft tut es in dem Datenzugriffsanwendungsblock in der Enterprise Library ist die beste, besonders für SQL Server:
ich verwenden, um Ihre Option zu verwenden, 1:
cmd.Parameters.Add ( "@ Name" SqlDbType.VarChar, 20) .Value = "Bob";
, die gut funktioniert, aber dann begann ich mit .AddWithValue und es ist so einfach, wie es nur geht. Es hat mir kein Problem nach vielen vielen tausend Anwendungen verursacht. Wohlgemerkt, ich fast immer meine Klassen privaten Variablen übergeben, so habe ich nicht so viel über die implizite Typumwandlung zu kümmern.
Es hängt von Ihrer Anwendung. Ich mag eigentlich 2, weil ich lke meine DAO nicht ändern zu müssen, wenn ich die Länge eines gespeicherten proc-Parameters ändern. Das ist nur mir aber. Ich weiß nicht, ob es irgendwelche Strafen oder etwas ist.