Laden...

Linq query datatable distincted

Erstellt von andi_bln vor 3 Jahren Letzter Beitrag vor 3 Jahren 439 Views
A
andi_bln Themenstarter:in
25 Beiträge seit 2014
vor 3 Jahren
Linq query datatable distincted

Verwendetes DatenbanksysAcc
AccessDatenbank
tem: <VSTO2019>

Hallo,

ich bin in einem DataTable mit mehreren einhunderttausend Recordsets unterwegs.
Mich interessieren nur 2 Spalten ( Spalte A und Spalte B )

Eine distincted Liste der Spalte A ist nicht weiter schlimm mit :


List<string> DTest = TestTable.AsEnumerable().Select(p => p.Field<string>(Layout.Test.ColA.ToString())).[b]Distinct()[/b].OrderBy(p => p).ToList();

ich bräuchte


Dictionary<string,string> DicTest = TestTable.AsEnumerable().Select(....................).ToDictionary(x=>x.Key,x=>x.Value)

wobei Value im Dictionary den dazugehörigen Wert in Spalte B repräsentiert ( der ist immer eindeutig, für den Wert in ColA )
Meine Versuche dauerten immer zu lange ( >20s ). Gibt es irgendeinen Trick, wie man das in einer LINQ - Anweisung blitzschnell erledigen könnte ?

Vielen Dank für jeden Tip.

Viele Grüße

Andreas

noch ?????

F
10.010 Beiträge seit 2004
vor 3 Jahren

Access ist keine Datenbank, sondern eine Datendatei, die durch den Jet-Treiber ( OleDb ) interpretiert wird. Jede Operation geht über die ganze Datei.
Wenn du eine echte DB wie z.b. SQLite benutzen würdest, wäre das wahrscheinlich in millisekunden passiert.

Und Du liesst hier die ganze DB vorher in eine DataTable, warum?

T
2.224 Beiträge seit 2008
vor 3 Jahren

Ich würde dir, wie FZelle, empfehlen die DB zu wechseln.
Dann kannst du zum einen auch mit Sqlite z.B. samt Indizies arbeiten, was der Performance allein schon gut tun würde.

Wenn du aber nicht wechseln willst, wäre mein Vorschlag, die Daten als Objekte vorzuladen.
Dann brauchst du diese nur als List<T> vorhalten und kannst die Daten im Speicher verarbeiten.
Wenn du die Abfrage häufig hast ggf. auch noch mit den gleichen Daten, dann würde ich die Daten sogar einmalig vorbereiten direkt beim vorladen.
Dann kannst du ggf. direkt auf ein fertiges Dictionery zugreifen.

Der Umstieg auf Sqlite ggf. noch mit EF Core oder alternativ Dapper wäre zu empfehlen um die einiges an Problemen zu ersparen.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

A
andi_bln Themenstarter:in
25 Beiträge seit 2014
vor 3 Jahren

Erstmal vielen Dank für Eure Rückantwort, ich habe vergessen zu sagen, dass ich aus einer riesigen Textdatei mit ziemlichen Aufwand einen DataTable erstelle, mir ist nichts blöderes eingefallen, das lässt sich vor allen Dingen auch mit einem DataGridview leicht darstellen.
War jetzt alles doof ausgedrückt.
In diesem DataTable lässt sich relativ leicht rechnen, dauert halt etwas.
Für diese Auswertung benötige ich nur die beiden Spalten, dort sollen nur die auftauchenden Messkanäle(A) mit den dazugehörigen Beschreibung(B) berechnet werden.
Letztendlich eine Auswahl für weitere Aktionen.
Das Mittel der Wahl ist für mich LINQ nur hier hänge ich ...

Viele Grüße
Andreas

noch ?????

A
andi_bln Themenstarter:in
25 Beiträge seit 2014
vor 3 Jahren

wie so oft, kommt einem die Lösung beim Schreiben:


 TestListe = TestTable.AsEnumerable().Select(p => p.Field<string>(TestLayout.A.ToString())+ "-->" + p.Field<string>(TestLayout.B.ToString())).Distinct().OrderBy(p => p).ToList();

und habe genau das was ich brauche blitzschnell 😉

Vielen Dank nochmal
Viele Grüße aus dem Lockdown

noch ?????

F
10.010 Beiträge seit 2004
vor 3 Jahren

Das einlesen einer TextDatei in eine List<Messwert> ist deutlich schneller und speicherschonender als eine Speicherfressende DataTable zu nehmen, und auch nicht komplizierter.

T
2.224 Beiträge seit 2008
vor 3 Jahren

Und zusätzlich könntest du dann deine Linq Anweisung in einem Rutsch schon beim einladen laufen lassen und die Daten dann direkt abfragen.
Dafür kannst du dann eine extra Property in der Klasse anlegen, dann sparst du dir das unnötige Select auf A und B.
Dann brauchst du nur einmal per Distinct und OrderBy die Liste zu erstellen.

Ich würde dafür einen Container Klasse anlegen.
Diese bekommt dann die Liste der Messwerte und generiert aus der Linq Anweisung einmalig eine eigene Liste.
Dann kannst du diese immer wieder verwenden ohne jedes mal die Linq Anweisung ausführen zu müssen.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.