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.

War es hilfreich?

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 der   SqlParameterCollection.Add Überlastung   das dauert String und SqlDbType   Enumerationswerts wo eine Weitergabe   integer mit der Zeichenfolge könnte   interpretiert als entweder die   Parameterwert oder das entsprechende   SqlDbType Wert. Verwenden AddWithValue   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:

http://msdn.microsoft.com/en-us/library /dd203144.aspx

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top