komplexes Filtern einer tDS-DataTable für ein WinForms-DGV [gelöst]

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 2 Antworten in diesem Thema. Der letzte Beitrag () ist von VaporiZed.

    komplexes Filtern einer tDS-DataTable für ein WinForms-DGV [gelöst]

    Hallo zusammen.

    Ich habe in meinem tDS eine Tabelle mit Kochrezepten. Eine weitere mit Zutaten. Diese Zutaten werden mit einer Hilfs-/Koppeltabelle mit den Rezepten verbunden (m:n-Relation), denn jede Zutat kann in mehreren Rezepten stehen und jedes Rezept wird natürlich mehrere Zutaten enthalten. Soweit so langweilig:

    Nun lasse ich mir in einem DGV die Rezeptnamen anzeigen. Allerdings will ich auch nach Zutaten suchen können, sodass ich sagen kann: »DGV, liste mir alle Rezeptnamen auf, die die Zutaten x, y, z enthalten.« Das MSDN macht klar, dass ich da den BindingSource-Filter vergessen kann, da Child-Rows nur per Aggregate-Funktion als Filterparameter herhalten können:

    MSDN schrieb:

    because child relationships may return multiple rows, you must include the reference to the child column in an aggregate function. For example, Sum(Child.Price) would return the sum of the column named Price in the child table.

    Nächste Variante wäre, dass ich der Rezepttabelle eine Boolean-Spalte ShowInDgv verpasse, den BindingSource-Filter darauf einstelle und per Code dann entscheide, bei welchem Rezept die Eigenschaft ShowInDgv auf True bzw. False gesetzt wird. Käme mir aber ziemlich falsch vor, weil dort m.E. z.B. Datentrennung nicht eingehalten wird. Denn was interessiert die Datentabelle, ob sie irgendwo angezeigt wird oder nicht? Außerdem wird dann ein zusätzlicher Wert beim Beenden mitgespeichert, den ich manuell resetten müsste. Effektiv gesehen, gehört dieser Wert einfach nicht in die Persistierung rein. Würde mich nicht wundern, wenn da noch mehr Murks entstehen würde.
    Eine Hilftabelle, die nur die RezeptID und dann die ShowInDgv-Property enthielt, könnte ich mir auch vorstellen. Leider kennt das tDS keine 1:1-Relation, sodass ich sagen könnte, dass ich quasi die Rezepttabelle durch eine Zusatzeigenschaft erweitere, ohne die Grundtabelle zu beeinflussen. Hätte den Vorteil, dass ich jene Tabelle nicht mit an die Speicherung übergeben müsste. Also per 1:n-Tabelle:

    Das Filtern wäre nur komplexer:

    VB.NET-Quellcode

    1. Dim IsVisible = False
    2. For Each VisibleRecipe In Tds.VisibleRecipes
    3. IsVisible = False
    4. Dim ListOfIngredientsInRecipe = VisibleRecipe.RecipesRow.GetIngredientsInRecipesRows
    5. For Each IngredientInRecipe In ListOfIngredientsInRecipe
    6. If IngredientInRecipe.IngredientsRow.Name = TxtIngretientsFilter.Text Then IsVisible = True : Exit For
    7. Next
    8. VisibleRecipe.IsVisible = IsVisible
    9. Next

    Wenn man jetzt mal von dem etwas einsilbigen TextBox-Filter absieht, da der natürlich nur erstmal für eine Filterzutat herhalten kann (denn man kann man ja problemlos alle Filterzutaten in ne ListBox hauen und dann auf Knopfdruck die Rezepte nach allen Zutaten fiiltern): Wie macht man es ggf. von Grundauf komplett anders besser?

    *Topic verschoben*
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Marcus Gräfe“ ()

    Nun endlich bin ich dazu gekommen, es bei MicDocs zu recherchieren und auszuprobieren. Meine ersten Versuche scheiterten, da mir .AsDataView nicht angezeigt wurden. Habe heute aber mal genauer nachgeschaut und dann fiel bei mir das 5-Cent-Stück. Als Extension muss man natürlich auch den passenden Namespace importieren. Nachdem ich also System.Data eingebunden hatte, stand die Extension natürlich zur Verfügung und läuft nun wie geschmiert. Für den Fall, dass es jemanden interessiert, wie ich nun filtere:

    VB.NET-Quellcode

    1. DgvShownRecipes.DataSource = Tds.Recipes.Where(Function(x) LbxIngredientsToFind.Items.Cast(Of Tds.IngredientsRow).Except(x.GetIngredientsInRecipesRows.Select(Function(z) z.IngredientsRow)).Count = 0).AsDataView
    Die Zutaten werden über eine ComboBox, die an die Zutatentabelle angebunden ist, zur Auswahl zur Verfügung gestellt. Wählt man eine Zutat aus, landet sie in einer ListBox. Und die Einträge jener ListBox werden als Filter hergenommen.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „VaporiZed“ ()