Hält die Verbindung offen, bis Sie fertig sind (vergessen Sie nicht, sie zu schließen!).
Kann normalerweise nur einmal wiederholt werden
Ist nicht so nützlich für die Aktualisierung auf die Datenbank
Auf der anderen Seite ist es:
Es befindet sich immer nur ein Datensatz im Speicher und nicht eine gesamte Ergebnismenge (dies kann RIESIG sein ).
Ist ungefähr so schnell wie möglich für diese eine Iteration
Ermöglicht es Ihnen, die Ergebnisse früher zu verarbeiten (sobald der erste Datensatz verfügbar ist). Für einige Abfragetypen kann dies auch eine sehr große Sache sein.
SqlDataAdapter / DataSet
Hiermit können Sie die Verbindung schließen, sobald das Laden der Daten abgeschlossen ist, und sie möglicherweise sogar automatisch für Sie schließen
Alle Ergebnisse sind im Speicher verfügbar
Sie können so oft wie nötig darüber iterieren oder sogar einen bestimmten Datensatz nach Index suchen
Verfügt über einige integrierte Funktionen zum Aktualisieren der Datenbank
Auf Kosten von:
Viel höhere Speichernutzung
Sie warten, bis alle Daten geladen sind, bevor Sie sie verwenden
Es hängt also wirklich davon ab, was Sie tun, aber ich bevorzuge einen DataReader, bis ich etwas brauche, das nur von einem Dataset unterstützt wird. SqlDataReader ist perfekt für den allgemeinen Datenzugriffsfall der Bindung an ein schreibgeschütztes Raster.
DataSet ist ein speicherinterner Datenspeicher, während der Datenleser nur ein Medium zum Abrufen der Daten ist. Außerdem können Sie Linq-Abfragen in DataSet ausführen, jedoch nicht in einem Datenleser.
Partha Choudhury
Mit ein wenig zusätzlichem Code können Sie tatsächlich Linq-Abfragen (oder mindestens eine Abfrage) auf einem Datenleser ausführen. Verwenden Sie einfach einen Iteratorblock, um die DataReader-Umwandlung als IDataRecord in Ihrer while (reader.Read())Schleife zurückzugeben.
Joel Coehoorn
7
Diese Antwort ist irreführend. Wenn Sie Ihre SqlConnection- und SqlDataReader-Objekte mit "using" -Anweisungen umschließen (wie Sie es ohnehin sollten, da sie nicht verfügbar sind), wird die Verbindung automatisch geschlossen. Und Sie können ein DataSet mit einem SqlDataReader verwenden: Rufen Sie einfach DataSet.Load (SqlDataReader) auf.
RickNZ
4
@RickNZ Seien Sie nicht zu schnell, wenn Sie Anweisungen verwenden, um Dinge für Sie zu schließen. Sie rufen die Dispose () -Methode des Objekts auf, nicht die Close () -Methode, und ich bin auf mindestens einen Fall gestoßen, in dem Dispose das Objekt für mich nicht tatsächlich geschlossen hat. Es ist immer am besten, einen expliziten Aufruf der close-Methode in den using-Block aufzunehmen.
Cdaragorn
5
@Cdaragorn Die MSDN-Dokumente sind normalerweise ziemlich klar über Close () vs. Dispose (). Im Fall von SqlConnection beispielsweise sagen die Dokumente, dass Close () und Dispose () funktional äquivalent sind. Ich habe keine Einwände gegen den Aufruf von Close (), aber Aufrufe von Dispose () sollten auch für alle IDisposables vorhanden sein - und der sauberste Weg, dies zu tun, ist eine using-Anweisung. In Fällen, in denen Sie wissen, dass Dispose () Close () nicht aufruft, sollten Sie Close () innerhalb eines finally-Blocks aufrufen, wenn Sie können, nicht innerhalb des using-Blocks (daher wird es immer noch aufgerufen, wenn es eine Ausnahme gibt).
RickNZ
17
Die Antwort darauf kann ziemlich weit gefasst sein.
Im Wesentlichen besteht der Hauptunterschied für mich, der normalerweise meine Entscheidung für die Verwendung beeinflusst, darin, dass Sie mit einem SQLDataReader Daten aus der Datenbank "streamen". Mit einem SQLDataAdapter extrahieren Sie die Daten aus der Datenbank in ein Objekt, das selbst weiter abgefragt werden kann, und führen CRUD-Operationen für aus.
Natürlich ist SQLDataReader mit einem Datenstrom VIEL schneller, aber Sie können jeweils nur einen Datensatz verarbeiten. Mit einem SQLDataAdapter haben Sie eine vollständige Sammlung der übereinstimmenden Zeilen zu Ihrer Abfrage aus der Datenbank, um mit Ihrem Code zu arbeiten / ihn zu durchlaufen.
WARNUNG: Wenn Sie einen SQLDataReader verwenden, stellen Sie IMMER, IMMER, IMMER sicher, dass Sie den richtigen Code zum Schließen der Verbindung schreiben, da Sie die Verbindung mit dem SQLDataReader offen halten. Andernfalls oder bei ordnungsgemäßer Fehlerbehandlung zum Schließen der Verbindung im Falle eines Fehlers bei der Verarbeitung der Ergebnisse wird Ihre Anwendung mit Verbindungslecks verkrüppelt .
Verzeihen Sie meine VB, aber dies ist die Mindestmenge an Code, die Sie bei Verwendung eines SqlDataReader haben sollten:
Wenn Ihr Ziel darin besteht, Daten mithilfe einer Auswahlabfrage für db abzurufen und nur in verschiedenen Zeilen auf diese Daten zuzugreifen, zur vorherigen Zeile usw. zu wechseln, können Sie den SQLDatareader verwenden und mit dtable.Load (rdr) in eine Datentabelle laden. Durchsuchen Sie dann diese Datentabelle nach oben und unten. Sie können diese Methode anstelle von DataAdapter verwenden ...
Variable
14
Ein SqlDataAdapter wird normalerweise zum Füllen eines DataSet oder einer DataTable verwendet, sodass Sie nach dem Schließen Ihrer Verbindung Zugriff auf die Daten haben (getrennter Zugriff).
Der SqlDataReader ist ein nur schneller Vorlauf und verbundener Cursor, der im Allgemeinen schneller ist als das Füllen eines DataSet / einer DataTable.
Darüber hinaus verarbeiten Sie mit einem SqlDataReader Ihre Daten Datensatz für Datensatz und speichern keine Daten im Speicher. Offensichtlich haben Sie mit einer DataTable oder einem DataSet einen Speicherzuweisungsaufwand.
Wenn Sie Ihre Daten nicht im Speicher behalten müssen, wählen Sie zum Rendern nur SqlDataReader. Wenn Sie nicht mit Ihren Daten umgehen möchten, wählen Sie den DataAdapter, um entweder ein DataSet oder eine DataTable zu füllen.
Verwenden Sie einen SqlDataAdapter, wenn Sie ein speicherinternes DataSet / DataTable aus der Datenbank füllen möchten. Sie haben dann die Flexibilität, die Verbindung zu schließen / zu trennen und die Datentabelle / das Set im Speicher weiterzugeben. Sie können die Daten dann bearbeiten und mithilfe des Datenadapters in Verbindung mit InsertCommand / UpdateCommand wieder in der Datenbank speichern.
Verwenden Sie einen SqlDataReader, wenn Sie einen schnellen Datenzugriff mit geringem Speicherbedarf wünschen, ohne dass Flexibilität erforderlich ist, um z. B. die Daten an Ihre Geschäftslogik weiterzuleiten. Dies ist optimaler für das schnelle Abrufen großer Datenmengen mit geringem Arbeitsspeicher, da nicht alle Daten auf einmal in den Speicher geladen werden. Beim SqlDataAdapter-Ansatz wird DataSet / DataTable also mit allen Daten gefüllt Es gibt viele Zeilen und Spalten, für deren Speicherung viel Speicher erforderlich ist.
Die Füllfunktion verwendet intern einen DataReader. Wenn Sie der Meinung sind, "Welches ist effizienter?", Ist die Verwendung eines DataReader in einer engen Schleife, die eine Sammlung Datensatz für Datensatz auffüllt, wahrscheinlich dieselbe Belastung für das System wie die Verwendung von DataAdapter.Fill.
while (reader.Read())
Schleife zurückzugeben.Die Antwort darauf kann ziemlich weit gefasst sein.
Im Wesentlichen besteht der Hauptunterschied für mich, der normalerweise meine Entscheidung für die Verwendung beeinflusst, darin, dass Sie mit einem SQLDataReader Daten aus der Datenbank "streamen". Mit einem SQLDataAdapter extrahieren Sie die Daten aus der Datenbank in ein Objekt, das selbst weiter abgefragt werden kann, und führen CRUD-Operationen für aus.
Natürlich ist SQLDataReader mit einem Datenstrom VIEL schneller, aber Sie können jeweils nur einen Datensatz verarbeiten. Mit einem SQLDataAdapter haben Sie eine vollständige Sammlung der übereinstimmenden Zeilen zu Ihrer Abfrage aus der Datenbank, um mit Ihrem Code zu arbeiten / ihn zu durchlaufen.
WARNUNG: Wenn Sie einen SQLDataReader verwenden, stellen Sie IMMER, IMMER, IMMER sicher, dass Sie den richtigen Code zum Schließen der Verbindung schreiben, da Sie die Verbindung mit dem SQLDataReader offen halten. Andernfalls oder bei ordnungsgemäßer Fehlerbehandlung zum Schließen der Verbindung im Falle eines Fehlers bei der Verarbeitung der Ergebnisse wird Ihre Anwendung mit Verbindungslecks verkrüppelt .
Verzeihen Sie meine VB, aber dies ist die Mindestmenge an Code, die Sie bei Verwendung eines SqlDataReader haben sollten:
äquivalentes C #:
quelle
Ein SqlDataAdapter wird normalerweise zum Füllen eines DataSet oder einer DataTable verwendet, sodass Sie nach dem Schließen Ihrer Verbindung Zugriff auf die Daten haben (getrennter Zugriff).
Der SqlDataReader ist ein nur schneller Vorlauf und verbundener Cursor, der im Allgemeinen schneller ist als das Füllen eines DataSet / einer DataTable.
Darüber hinaus verarbeiten Sie mit einem SqlDataReader Ihre Daten Datensatz für Datensatz und speichern keine Daten im Speicher. Offensichtlich haben Sie mit einer DataTable oder einem DataSet einen Speicherzuweisungsaufwand.
Wenn Sie Ihre Daten nicht im Speicher behalten müssen, wählen Sie zum Rendern nur SqlDataReader. Wenn Sie nicht mit Ihren Daten umgehen möchten, wählen Sie den DataAdapter, um entweder ein DataSet oder eine DataTable zu füllen.
quelle
Verwenden Sie einen SqlDataAdapter, wenn Sie ein speicherinternes DataSet / DataTable aus der Datenbank füllen möchten. Sie haben dann die Flexibilität, die Verbindung zu schließen / zu trennen und die Datentabelle / das Set im Speicher weiterzugeben. Sie können die Daten dann bearbeiten und mithilfe des Datenadapters in Verbindung mit InsertCommand / UpdateCommand wieder in der Datenbank speichern.
Verwenden Sie einen SqlDataReader, wenn Sie einen schnellen Datenzugriff mit geringem Speicherbedarf wünschen, ohne dass Flexibilität erforderlich ist, um z. B. die Daten an Ihre Geschäftslogik weiterzuleiten. Dies ist optimaler für das schnelle Abrufen großer Datenmengen mit geringem Arbeitsspeicher, da nicht alle Daten auf einmal in den Speicher geladen werden. Beim SqlDataAdapter-Ansatz wird DataSet / DataTable also mit allen Daten gefüllt Es gibt viele Zeilen und Spalten, für deren Speicherung viel Speicher erforderlich ist.
quelle
Die Füllfunktion verwendet intern einen DataReader. Wenn Sie der Meinung sind, "Welches ist effizienter?", Ist die Verwendung eines DataReader in einer engen Schleife, die eine Sammlung Datensatz für Datensatz auffüllt, wahrscheinlich dieselbe Belastung für das System wie die Verwendung von DataAdapter.Fill.
(System.Data.dll, System.Data.Common.DbDataAdapter, FillInternal.)
quelle