Filtern mit ADO
-
Hallo!
Ich arbeite noch nicht lange mit ADO und habe mir mit schweißtreibender Arbeit die ersten Basics angeeignet.
Jetzt allerdings stehe ich vor einem Problem, das ich noch nicht habe lösen können.
Ich möchte gerne innerhalb einer DataRowCollection filtern, also bspw. alle Datensätze deren "TEST_IRGENDWAS" = 200 ist. Als Ergebnis erwarte ich natürlich auch eine DataRowCollection, da es ja mehrere DataRows sein können, die diesem Kriterium erfüllen.
Oder bin ich auf dem völlig falschen Weg und muß vielleicht das DataSet filtern?
-
hmm mir fallen da nur zwei Möglichkeiten ein!
1. die entsprechenden Spalten jeder DataRow per if .... else ... switch
innerhalb einer Schleife for ... foreach durchlaufen und Ergebnisse in
neue Collection schieben2. ADO ist doch die Schnittstelle zu SQL also macht man die Filterung
zweckmäßigerweise per SQL und nicht im C#-Code und dergleichen
select * from personal where alter >= 50Was willst Du mehr?
mfg sclearscreen
-
Manuell filtern geht so siehe Beispiel
string txt = this.dsPersonal.Tables["person"].Rows[0]["name"].ToString(); if(txt == "....") { // mache was }
vorsichtshalber wenn ich nicht weiss wie oder damit egal ist wie die Daten vom Typ gehalten werden, hänge ich immer die Methode
.ToString();
an!
und schiebe es inne string-VariabledsPersonal ist ein DataSet nur um Unklarheit zu beseitigen!
DataSet lässt sich ja aus DB-Abfragen und auch aus XML-Dokumenten bilden.
-
Es gibt doch auch die Funktion DataRowCollection.Find(...), deren Ergebnismenge immer <= 0 (wg. Primary Key). Gibts nicht ein ähnliches Verfahren für meine Problemstellung?
1. die entsprechenden Spalten jeder DataRow per if .... else ... switch innerhalb einer Schleife for ... foreach durchlaufen und Ergebnisse in neue Collection schieben
So habe ich es bislange auch lösen müssen ... ist dieses Vorgehen in der Praxis tatsächlich üblich (ich hab ja keine Ahnung, und will einen schönen Code haben)
2. ADO ist doch die Schnittstelle zu SQL also macht man die Filterung zweckmäßigerweise per SQL und nicht im C#-Code und dergleichen select * from personal where alter >= 50
Es gibt ein DataGridView, welches an den entsprechenden DataAdapter hängt. Ich kann den nicht mit einer WHERE-Klausel einschränken, ansonsten ändert sich ja auch der Inhalt der Gridview ...
-
Ob irgendetwas in der Praxis gemacht wird oder nicht ist nicht die Frage.
Soweit eine Lösung das gewünschte Ergebniss liefert und das das dann och in entsprechender Zeit (Performance) geschieht wird es auch angewandt.
Alles andere würde sonst nur die Kreativität derer einschränken die die Lösung konkret implementieren müssen.Und um auf die Methode
Find(...)
zurückzukommen (ist eine Methode der Klasse DataRowCollection) siehe folgendes Beispiel
private void FindInMultiPKey(DataTable myTable){ DataRow foundRow; // Create an array for the key values to find. object[]findTheseVals = new object[3]; // Set the values of the keys to find. findTheseVals[0] = "John"; findTheseVals[1] = "Smith"; findTheseVals[2] = "5 Main St."; foundRow = myTable.Rows.Find(findTheseVals); // Display column 1 of the found row. if(foundRow != null) Console.WriteLine(foundRow[1]); }
was will uns der Beispiel-Code und die MSDN sagen
Du bekommst kein DataRowCollection als Rückgabewert
sonder nur eine einzelne DataRow
wichtig ist die Datenquelle muss logischerweise wie auch die MSDN sagt mindestens ein Splate haben.
Das Array worauf Du sicherlich spekulierst enthält ein Menge von Werten nach denen gesucht wird! Eine Übereinstimmung bringt genau die eine gefunden Zeile.Nur am Rande:
Das Feld mit den Suchwerten ist vom Typ Object damit ist egal ob nach nummerischen Werten oder nach Zeichketten gesucht wird! Da alle Typen von Object abstammen erbt jede Klasse die Methode GetType, womit dieFind-Methode intern den richtigen Datetyp auswählen kann.
Wie gesagt Du bekommst mit Find nur eine Zeile (DataRow) wird nichts gefunden ist bekommt in C# null das kann man dann auch wieder mit if ... else abfragen.
Und noch aufpassen diese Methode kann laut MSDN 2 Exceptions werfen!
Das haben die sogar in Ihrem Beispiel versiebt, weil in obiger Methodenimplementierung fehlt try/catchmfg sclearscreen
P.S.:
Hilfe/MSDN benutzen sollte nochmehr Klarheit bringen
und geleichmal testenSomit musst Du immernoch bei Find mittels einer Schleife sebst nachmanipulieren und wieder selbst eintüten. Und dann muss diese manipulierte DataTable nur noch der DataSource-Eigenschaft des DataGrid/View zugewiesen werden fertig.
-
Sabine_t1000 schrieb:
Es gibt ein DataGridView, welches an den entsprechenden DataAdapter hängt. Ich kann den nicht mit einer WHERE-Klausel einschränken, ansonsten ändert sich ja auch der Inhalt der Gridview ...
Das ist nur die halbe Wahreit!
Du nimmst bestimmt auch den Abfragegenerator?
Selbst diese Statments kann man zur Laufzeit ändern.Dann bindet man das nicht statisch über die Eigenschaftsleiste während der Entwurfszeit sonder zur Laufzeit. Und es geht auch ohne die Adapter. Desweiteren hat der Adapter ja uch bloss 4 Kommandos zur Manipulation in SQL gibts ja auch nur
4 Möglichkeiten in SQL Insert, Delete, Select und Update
Sofern Du das auch bei dem Autogenerierungsassistenten beim Adaptererstellen zulässt gibts beim Adapter dann maximal 4 oder weniger Kommandos.Diese kann man alle zur LAufzeit als Programmierer noch nachmanipuieren.
Man kann sogar noch Kommandos löschen und wieder neue einhängen in den Adapter.
Ein ADO.NET-Buch von MicrosoftPress zeigt da alles was möglich ist.Dann kann man die Eigenschaft DataSource des DataGrid/View auch zur Laufzeit manipulieren. Diesem teil kann man somit zur Laufzeit ein DataSet oder besser noch ein DataTable unterjubeln.
mfg sclearscreen
-
Such mal bei Dir in der MSDN unter
DataTable.Compute
-
wenn Du mit den Daten im Grid arbeiten musst und es sollen totzdem die Daten in der Ansicht des Grid erhalten bleiben, kannst Du auch mit mehreren DataSets arbeiten!
Kopiere die Daten des DataSet was ans DataGrid gebunden ist einfach in ein zweites
DataSet und manipuliere das um vielleicht irgendwelche statistischen Sachen anzustellen.Was spricht dagegen mehrere DataSet einzustzen dann kannste dort nach belieben löschen, ändern, entfernen und Werte zählen die irgend etwas entsprechen etc.
weiss der Teufel.mfg sclearscreen
-
Aus der MSDN:
DataView bietet mehrere Möglichkeiten zum Sortieren und Filtern von Daten in einer DataTable:Mit der Sort-Eigenschaft können Sie einzelne oder mehrere Sortierreihenfolgen für Spalten angeben und die Parameter ASC (ascending = aufsteigend) und DESC (descending = absteigend) einfügen.
Mit der ApplyDefaultSort-Eigenschaft können Sie eine Sortierreihenfolge automatisch in aufsteigender Reihenfolge, basierend auf der Primärschlüsselspalte oder den Spalten der Tabelle erstellen. ApplyDefaultSort kann nur angewendet werden, wenn es sich bei der Sort-Eigenschaft um einen NULL-Verweis oder eine leere Zeichenfolge handelt und wenn für die Tabelle ein Primärschlüssel definiert wurde.
Mit der RowFilter-Eigenschaft können Sie Teilmengen von Zeilen angeben, die auf den Spaltenwerten basieren. Einzelheiten zu gültigen Ausdrücken für die RowFilter-Eigenschaft finden Sie in den Referenzinformationen für die Expression-Eigenschaft der DataColumn-Klasse.
Wenn Sie die Ergebnisse einer bestimmten Abfrage von Daten zurückgeben möchten, anstatt eine dynamische Ansicht von einer Teilmenge von Daten zu erhalten, verwenden Sie die Methoden Find oder FindRows der DataView, denn sie sind für diesen Zweck besser geeignet als die RowFilter-Eigenschaft. Wenn Sie die RowFilter-Eigenschaft festlegen, wird der Index für die Daten neu erstellt, wodurch zusätzlicher Verwaltungsaufwand für die Anwendung entsteht und die Leistung verringert wird. Die RowFilter-Eigenschaft wird am besten in einer datengebundenen Anwendung verwendet, in der ein gebundenes Steuerelement gefilterte Ergebnisse anzeigt. Die Methoden Find und FindRows nutzen den aktuellen Index, ohne dass der Index neu erstellt werden muss. Weitere Informationen über die Methoden Find und FindRows finden Sie unter Durchsuchen einer DataView.Mit der RowStateFilter-Eigenschaft können Sie angeben, welche Zeilenversionen angezeigt werden. Die DataView verwaltet implizit, welche Zeilenversion, abhängig vom RowState der zugrunde liegenden Zeile, verfügbar gemacht werden soll. Wenn z. B. DataViewRowState.Deleted für den RowStateFilter festgelegt ist, macht die DataView die Original-Zeilenversion aller gelöschten (Deleted) Zeilen verfügbar, weil es keine aktuelle (Current) Zeilenversion gibt. Mit der RowVersion-Eigenschaft der DataRowView können Sie feststellen, welche Zeilenversion einer Zeile verfügbar gemacht wird.
Die folgende Tabelle enthält die Optionen für DataViewRowState.DataViewRowState Beschreibung
CurrentRows Die Current-Zeilenversion von allen Zeilen mit dem Status Unchanged, Added und Modified. Dies ist die Standardeinstellung.
Added Die Current-Zeilenversion von allen Added-Zeilen.
Deleted Die Original-Zeilenversion von allen Deleted-Zeilen.
ModifiedCurrent Die Current-Zeilenversion von allen Modified-Zeilen.
ModifiedOriginal Die Original-Zeilenversion von allen Modified-Zeilen.
None Keine Zeilen.
OriginalRows Die Original-Zeilenversion von allen Zeilen mit dem Status Unchanged, Modified und Deleted.
Unchanged Die Current-Zeilenversion von allen Unchanged-Zeilen.Weitere Informationen zu Zeilenstatus und Zeilenversionen finden Sie unter Zeilenstatus und Zeilenversion.
Im folgenden Codebeispiel wird eine Ansicht erstellt, die alle Produkte anzeigt, bei denen die Einheiten im Lager kleiner als oder gleich der Neusortierungsebene ist, wobei zuerst nach der Lieferanten-ID und dann nach dem Produktnamen sortiert wird.
[Visual Basic]
Dim prodView As DataView = New DataView(prodDS.Tables("Products"), _
"UnitsInStock <= ReorderLevel", _
"SupplierID, ProductName", _
DataViewRowState.CurrentRows)[C#]
DataView prodView = new DataView(prodDS.Tables["Products"],
"UnitsInStock <= ReorderLevel",
"SupplierID, ProductName",
DataViewRowState.CurrentRows);Also, statt umständlich über die DataRowCollection zu gehen, einfach das DataView benutzen!
-
DataView ... genau das ist es, was ich gesucht habe. Vielen Dank!