ADO.NET Datentabelle vs. Datenleser

8

Der DataReader ist effizienter als eine DataTable, wenn Sie nur Daten anzeigen, aber nicht manipulieren müssen. Um jedoch einen DataReader von der Datenzugriffsebene zu erhalten, sollte ich das Verbindungsobjekt offen lassen? Ich denke, das ist auch ein sehr großes Effizienzproblem. Gibt es einen anderen Ansatz, um den DataReader voll auszunutzen?

    
erasmus 10.03.2010, 19:04
quelle

9 Antworten

10

Ja, der Datenleser ist definitiv der effizienteste - aber Sie möchten nicht eine Verbindung für längere Zeit geöffnet lassen!

  • Verwenden Sie DataReader , um Ihre Daten in ein Entitätsobjekt einzulesen; Öffnen Sie die Verbindung, lesen Sie die Daten, schließen Sie die Verbindung
  • Machen Sie alles, was Sie mit Ihrem Geschäftsobjekt tun müssen
  • speichert die Änderungen zurück, z. mithilfe einer Ad-hoc-SQL-Abfrage, einer gespeicherten Prozedur oder was auch immer Sie möchten; Nochmals: Öffnen Sie die Verbindung, schreiben Sie die Änderungen zurück, schließen Sie die Verbindung

Das ist wahrscheinlich das effizienteste, was Sie bekommen können - es ist ein bisschen Arbeit, ein bisschen langweiliger Code und alles, aber es geht ungefähr so ​​schnell es geht.

Wenn Sie mehr an der Produktivität von Entwicklern als an roher Geschwindigkeit interessiert sind, warum verwenden Sie nicht irgendeine Art von ORM, um all das langweilige, nervige Mapping hin und her zu machen? Speichert Sie viel Code und unordentliches Zeug, das Sie pflegen müssen!

    
marc_s 10.03.2010, 19:08
quelle
3

Ich habe niemals einen DataReader in die Wildnis gelassen (außerhalb der DAL). Es ist nur eine Frage der Zeit, bevor Sie Verbindungen irgendwo offen lassen. Außerdem bin ich fast nie mit so vielen Daten bei einem einzelnen Aufruf beschäftigt, bei dem das Umgehen einer DataTable oder eines DataSets ein Problem darstellt.

Wir benutzen eine objektorientierte Sprache und die DAL kann das wirklich nutzen. In Ihrem Projekt sollte nur eine Codezeile die Verbindungszeichenfolge enthalten. Nur ein Objekt, das die Datenbank tatsächlich berührt (ruft ExecuteNonQuery, DA.Fill () usw. auf)

Damit können Sie sich auch sehr gut mit der Protokollierung von Ausnahmen usw. befassen, da Sie dies nur einmal tun. Also habe ich in der einen DAL-Basisklasse, die ich für alle meine DAL-Objekte in meinem gesamten Projekt verwende, die Logik, dass, wenn die DAL eine Ausnahme auslöst, diese in einer Tabelle in meiner Datenbank protokolliert wird. Diese Protokollierung schlägt auf eine Textdatei fehl, wenn die Datenbankprotokollierung fehlschlägt.

%Vor%

Da ich all dies verkapsele, sieht mein Code zum Abrufen der Daten jetzt so aus:

%Vor%

(oder wahrscheinlicher ist ein BAL-Objekt zwischen den 2). Der DB ist ein normales Objekt (nicht statisch), wird aber nur einmal pro Anwendung instanziiert.

    
JBrooks 10.03.2010 20:00
quelle
2

Lassen Sie Ihre Datenschicht Objekte zurückgeben, keine Datatables oder Datenlesegeräte. Ich würde vorschlagen, dass Sie Ihre Objekte mit einem Datenlesegerät bevölkern.

    
Robert 10.03.2010 19:10
quelle
1

Normalerweise öffne ich den Reader mit CommandBehavior.CloseConnection. Dann laufe ich durch den Reader und lese die Daten in mein eigenes Objektmodell oder eine Liste oder was auch immer im Speicher mit den Daten und schließe dann den Reader. Es macht viel von dem gleichen Zeug wie eine Datentabelle, aber ich hasse es einfach, mit aufgeblähten und lose typisierten Datenstrukturen umzugehen.

    
Mike Mooney 10.03.2010 19:10
quelle
1

Lassen Sie uns einen albernen Benchmark verwenden, um zu überprüfen, wie viel schneller der DataReader (.Net Version 4) ist. Ich habe einen Datensatz aus der Datenbank (SQL Server 2000) abgerufen und alle Felder gelesen. Ich habe diesen Vorgang 1000 Mal wiederholt. DataReader benötigte 17,3327585 Sekunden und DataTable 18,37320156 und so ist DataReader ~ 1,04 Sekunden schneller als DataTable für 1000 Lesevorgänge.

So würde man einen Leistungsgewinn von 0,00104 Sekunden erhalten, wenn DataReader gegenüber DataTable bevorzugt wird.

Schauen Sie Ist DataSet langsamer als DataReader wegen ...? auch

    
bjan 14.05.2012 07:10
quelle
0

Als ich das vorher recherchiert habe, glaube ich, dass ich entdeckt habe, dass der Leistungsunterschied zwischen DataReader und DataTable trivial war, abgesehen von vielleicht sehr großen Datenmengen. Seitdem habe ich typischerweise DataTable verwendet, da es voll funktionsfähiger ist, mit getrennten Verbindungen usw. gearbeitet werden kann.

    
alchemical 10.03.2010 19:17
quelle
0

Wenn Sie die Verbindungen und Zeremonien von ADO.NET vollständig abstrahieren möchten, ist der DataReader eine kleine Herausforderung. Ich mag es wirklich nicht, dass mein Daten-Tool eine offene Verbindung hat, hoffend dass der DataReader entsorgt wird (vorausgesetzt, Sie haben die Option CommandBehavior.CloseConnection verwendet). Wenn Sie viele DataReader verwenden, ist es außerdem schwierig, Verbindungen zu poolen, da Sie mit der Verbindung nichts anfangen können, bis der vorherige DataReader geschlossen ist. Sie können nicht leicht herumgereicht werden. Ihr Data-Tool ist keine echte Abstraktion.

DataTables andererseits sind extrem flexibel und können einen sehr effizienten, klaren Code liefern. Linq-To-DataTable ist großartig. Zum Glück ist die DataTable eigentlich ziemlich effizient . Für nicht große Ergebnismengen ist es fast so schnell wie der Datenreader. (Es hängt natürlich von genau dem ab, was Sie tun.) Immer mehr bekomme ich DataTables von meinem Datentool statt von Lesern. Es macht das Leben wirklich einfach. Ich kann weiterhin dieselbe offene Verbindung verwenden. Es gibt keinen "Zustand" im Datentool.

Der Code zum Abrufen eines DataReader ist sehr einfach. Wenn ich also wirklich einen DataReader brauche (nicht oft), lasse ich mir von meiner DAL meine Verbindung geben und erhalte meinen DataReader selbst.

    
Patrick Karcher 10.03.2010 19:08
quelle
0

Direkt aus der Dokumentation :

  

Wenn Sie mehrere Datenzeilen abrufen müssen, um das zu tun   die Daten auf andere Weise anzeigen oder verarbeiten, haben Sie zwei grundlegende   Entscheidungen. Sie können ein DataSet-Objekt oder ein DataReader-Objekt verwenden.

     

Der DataReader-Ansatz ist in der Regel schneller, weil er das vermeidet   Overhead, der mit dem Erstellen eines DataSet-Objekts verbunden ist. Das   Overhead, der einem DataSet-Objekt zugeordnet ist, umfasst das Erstellen   DataSet-Unterobjekte wie DataTables, DataRows und DataColumns.   Der DataReader bietet jedoch weniger Flexibilität und ist weniger geeignet   in Situationen, in denen Sie Daten zwischenspeichern und an die Daten weitergeben müssen   Komponenten in einer Anwendung mit mehreren Ebenen.

     

Hinweis: Der DataAdapter, der zum Füllen des DataSet verwendet wird, verwendet intern einen DataReader.

     

Verwenden Sie einen DataReader, wenn die folgenden Bedingungen zutreffen:

     

• Sie benötigen einen Nur-Lese-Zugriff auf Daten (den Feuerwehrschlauch)   Szenario), und Sie möchten so schnell wie möglich auf die Daten zugreifen und   Sie müssen es nicht zwischenspeichern.

     

• Sie haben einen Datencontainer, beispielsweise eine Geschäftskomponente   Legen Sie die Daten ein.

     

Verwenden Sie ein DataSet, wenn die folgenden Bedingungen zutreffen:

     

• Sie müssen die Daten zwischen den Ebenen zwischenspeichern oder übergeben.

     

• Sie benötigen eine relationale In-Memory-Ansicht der Daten für XML oder   Nicht-XML-Manipulation.

     

• Sie möchten einige oder alle abgerufenen Zeilen aktualisieren, und Sie möchten   Verwenden Sie die Stapelaktualisierungsfunktionen der SqlDataAdapter-Klasse.

     

• Sie müssen Daten an einen Kontrolltyp binden, den der DataReader nicht kann   gebunden sein an. Viele Windows Forms-Steuerelemente, die Daten binden können   erfordern eine Datenquelle, die die IList-Schnittstelle implementiert. Das DataSet   implementiert IList, aber der DataReader implementiert IEnumerable.   IEnumerable unterstützt die Datenbindung an die meisten Web Form-Steuerelemente, jedoch nicht an   bestimmte Windows Forms-Steuerelemente. Überprüfen Sie die Datenquellenanforderungen für   der bestimmte Steuerelementtyp, den Sie binden möchten.

     

• Sie müssen gleichzeitig auf mehrere Datensätze zugreifen   möchte Serverressourcen nicht offen halten.

Obwohl wir über DataSet sprechen, gilt das meiste für DataTable . Aus Effizienzsicht ist hier ein seltenes Benchmarking von msdn selbst . Die untere Zeile ist DataReader ist marginal schneller, und wenn es darauf ankommt ..

Siehe diese verwandte Frage auch, die einige coole vorschlägt ORMs und Benchmarking.

    
nawfal 05.02.2013 20:45
quelle
0

Dies ist das gleiche wie ich hier gepostet habe.

Ich habe selbst einige Benchmarks mit verschiedenen Ansätzen gemacht:

%Vor%

1 und 2 gibt DataTable zurück, während der rest stark typisierte Ergebnismenge, also ist es genau nicht Äpfel mit Äpfeln, aber ich während sie Zeit entsprechend.

Nur das Wesentliche:

%Vor%

Die Abfrage hat ungefähr 1200 Zeilen und 5 Felder zurückgegeben (100 Mal ausgeführt). Abgesehen von Read1 haben alle gut abgeschnitten. Von allen bevorzuge ich Read3 , die Daten, wie aufgezählt, träge zurückgibt. Das ist großartig für Speicher, wenn Sie es nur aufzählen müssen. Um eine Kopie der Sammlung im Speicher zu haben, ist es besser mit Read4 oder Read5 wie gewünscht.

    
nawfal 13.02.2013 18:54
quelle

Tags und Links