Linq, mehrere Tabellen, gruppieren - Verständnisfrage

  • VB.NET

Es gibt 30 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Linq, mehrere Tabellen, gruppieren - Verständnisfrage

    Hallo zusammen,

    habe eine alte Access Abfrage

    SQL-Abfrage

    1. SELECT Artikel_variable_Datentabelle_Felder.Bezeichnung, Artikel_variable_Datentabelle_Felder.EingabemaskeID, Artikel_variable_Datentabelle_Root_0_Bereiche.TreeViewHauptpunkte, Artikel_variable_Datentabelle_Root_0_Bereiche.Anzeigereihenfolge, Artikel_variable_Datentabelle_Felder.Anzeigereihenfolge
    2. FROM (Artikel_variable_Datentabelle_Root_1_Bereiche LEFT JOIN Artikel_variable_Datentabelle_Felder ON Artikel_variable_Datentabelle_Root_1_Bereiche.FeldnameID = Artikel_variable_Datentabelle_Felder.ID) LEFT JOIN Artikel_variable_Datentabelle_Root_0_Bereiche ON Artikel_variable_Datentabelle_Felder.TreeViewRoot0ID = Artikel_variable_Datentabelle_Root_0_Bereiche.ID
    3. GROUP BY Artikel_variable_Datentabelle_Felder.Bezeichnung, Artikel_variable_Datentabelle_Felder.EingabemaskeID, Artikel_variable_Datentabelle_Root_0_Bereiche.TreeViewHauptpunkte, Artikel_variable_Datentabelle_Root_0_Bereiche.Anzeigereihenfolge, Artikel_variable_Datentabelle_Felder.Anzeigereihenfolge
    4. HAVING (((Artikel_variable_Datentabelle_Felder.EingabemaskeID)=1))
    5. ORDER BY Artikel_variable_Datentabelle_Root_0_Bereiche.Anzeigereihenfolge, Artikel_variable_Datentabelle_Felder.Anzeigereihenfolge;


    und möchte diese jetzt in VB.Net 2017 in Linq umsetzen, damit dies in einem DataGridView angezeigt wird.

    Habe dazu ein Modul Abfrage in der dann alle Abfragen drin stehen. (Erhoffe mir dadurch ein leichteren Überblick und evtl. Pflege)

    VB.NET-Quellcode

    1. Public Function TreeView_Suche1(EingabemaskeID_Filter As Integer, DGridView As DataGridView) As String
    2. ' In Access alte Daten-DB: Abfrage 2
    3. Dim LINQ_String = From DT1 In Hauptmaske._Modelldatenbank_VB_Net_2019_DatenDataSet.Artikel_variable_Datentabelle_Root_1_Bereiche
    4. Join DT2 In Hauptmaske._Modelldatenbank_VB_Net_2019_DatenDataSet.Artikel_variable_Datentabelle_Felder
    5. On DT1.FeldnameID Equals DT2.ID
    6. Join DT3 In Hauptmaske._Modelldatenbank_VB_Net_2019_DatenDataSet.Artikel_variable_Datentabelle_Root_0_Bereiche
    7. On DT2.TreeViewRoot0ID Equals DT3.ID
    8. Where DT2.EingabemaskeID = EingabemaskeID_Filter
    9. Order By DT3.Anzeigereihenfolge Ascending, DT2.Anzeigereihenfolge Ascending
    10. Select DT2.Bezeichnung, DT2.EingabemaskeID, DT3.TreeViewHauptpunkte, DT3.Anzeigereihenfolge, Anzeigereihenfolge2 = DT2.Anzeigereihenfolge
    11. 'Group By DT2.Bezeichnung, DT2.EingabemaskeID, DT3.TreeViewHauptpunkte, DT3.Anzeigereihenfolge, Anzeigereihenfolge2 = DT2.Anzeigereihenfolge
    12. DGridView.DataSource = LINQ_String.ToList
    13. End Function


    Was ich bisher verstanden habe
    DT1-DT3 sind die einzelnen Tabellen und somit der Zugriff auf dessen Felder
    Join fügt weitere Tabellen hinzu
    on .. Equals verbindet zwei Tabellen und deren Felder miteinander
    Where ist die Bedindung(en), die erfüllt sein müssen für die Filterung
    Order By ist die Sortierung der einzelnen Tabellenfelder
    Select ist dann die Anzeigereihenfolge der gewünschten Tabellenfelder der jeweiligen Tabelle.

    Was ich aber leider jetzt noch gar nicht verstehe ist das Gruppieren (somit das reduzieren auf einmalige Datensätze). Aktuell sind es weit über 44.000. Es sollten aber nur knapp 60 sein.

    Das Anzeigen des Ergebnisses im DGV klappt schon.

    Könntet Ihr mir kurz auf die Sprünge helfen.

    An welcher Stelle kommt die Group Anweisung hin und wie müsste ich die dann aufbauen?

    Vielen Dank

    Volker

    P.S. Das Ganze ist für eine Suchfunktion gedacht, in der der Benutzer je nach Eingabemaske sich ein Feld aussuchen kann, in dem dann anschließend gesucht wird. Da die Felder für jede Eingabemaske andere sind, muss das Ganze über Tabelleneinträge geregelt werden. Der Benutzer soll später auch noch eigene Felder hinzufügen können.
    SQL kann man nicht 1:1 nach Linq übersetzen.
    Einfache Sachen schon, aber so fortgeschrittenen Kram wie Left join und Having - glaub nicht.
    Ich sag "glaub nicht", weil ich ziemlich schlecht bin in SQL, und mir nicht ganz sicher, ob ich zB Left Join in allen seinen Auswirkungen wirklich verstehe. Puh - und Having noch dazu...

    Ah - fällt mir ein: Könnte sein, dass die Linq-Formulierung Group Join eine Art Annäherung an Sql-LeftJoin ist.
    Aber Group Join ist wiederum fortgeschrittener Linq-Kram, und hab ich auch nur ein einziges Mal was mit gemacht (und vergessen was).

    Tipp noch: Sieh zu, dass deine Benamung kurz und sprechend ist.
    Artikel_variable_Datentabelle_Felder.Bezeichnung ist vielleicht sprechend (weiss ich nicht - ist mir zu lang zum lesen), aber so lang, dass Code damit auch wieder vollkommen unleserlich ist.
    DT2.Bezeichnung ist kurz, aber was ist ein DT2?

    Dim LINQ_String = ... ist ganz falsch - es ist bestimmt kein String.

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

    Hallo EDR,

    vielen Dank erst einmal für die so späte Antwort.

    Ich kann es kaum glauben, dass Du in etwas schlecht bis (grins). Aber man kann ja schließlich auch nicht alles können.

    Na gut das mit dem Tabellennamen ist tatsächlich nicht die beste Benennung. Mal schauen, ob ich das noch ändern.

    DT1-DT3 soll für DataTable stehen und halt die einzelnen Tabellen darstellen über die ich dann die Felder ansprechen kann. Da ich ja die Access-SQL Abfragen habe, wird diese SQL - Abfrage schnell in Access eingefügt, dann in die Entwurfsansicht gewechselt und dann bekommt jede Tabelle von links nach rechts gesehen eine DTx - Benennung. Wie gesagt, denn bisherigen Aufbau habe ich auch schon ganz gut verstanden und er ist bis hier her auch logisch und gut zu händeln. Aber das mit dem Gruppieren und dann noch über mehrere Tabellen ist leider auch mit der Suche im Internet nicht leichter zu verstehen bzw. für meinen Fall auch noch nichts passendes gefunden.

    Ja, hast ja rechts, dass LINQ kein String ist. Werde ich gleich mal in LINQ_Query ändern.

    Mal schauen, ob es hier jemanden gibt, der sich mit LINQ besser auskennt.

    Schöne Pfingsten noch.

    Gruß

    Volker

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Volker Bunge“ ()

    Volker Bunge schrieb:

    DT1-DT3 soll für DataTable stehen und halt die einzelnen Tabellen darstellen über die ich dann die Felder ansprechen kann.
    Ja, aber eine Tabelle bedeutet etwas.
    Also du tust ja nicht Artikel-Daten in eine MesswertTabelle speichern.
    Und wie das, was sie bedeutet, muss sie auch heissen.
    Du hast in Access ein Datenmodell angelegt - ein Modell!!
    Und Modell bedeutet, dass Dinge im Modell Dingen in der Realität gleichen.
    Und das beste Mittel, diese Ähnlichkeiten hervorzuheben ist eben die Benamung. "Nomen est Omen" - dassis ganz ernst gemeint.
    Das DT2 eine Tabelle ist, weiss ich selbst. In einem typisierten Dataset gibts ja nix anneres als Tabellen, welche so einen Namen annehmen könnten.
    Wenn ich also frage

    ErfinderDesRades schrieb:

    was ist ein DT2?
    Dann setze ich das gesagte voraus, also das, was du DT2 genannt hast, muss es auch in der Wirklichkeit geben.
    Jo - kenne ich aber nicht, und du vmtl auch nicht.

    Vielleicht sollte ich einfacher fragen: Was in der Realität entspricht dem, was du in deim Datenmodell DT2 genannt hast?

    Aber das ändert erstmal nix daran, dassich dein Problem nicht lösen kann - jedenfalls nicht so prinzipiell, wie du das evtl. gedacht hast.
    Aber du kannst ja mal "Linq group join" googeln (falls noch nicht geschehen).
    Hallo zusammen,

    bin jetzt mit meiner Abfrage schon etwas weiter gekommen.

    Natürlich gibt es wieder ein Problem.

    Wie im Eingangspost schon gezeigt, fülle ich ein DGV über eine Abfrage die zwei Tabellen zu einem Ergebnis zusammenfügt (soweit läuft das auch).

    Jetzt möchte ich dieses DGV filtern.

    Da es ja keine eigene Bindingsource hat (zu mindestens steht unten in der Anzeige wo die Bindingsource stehen, keines für dieses DGV) , geht das nicht so wie bei den Artikeln.

    Ein möglicher Suchstring würde dann so aussehen:
    EingabemaskeID = 1 and (CONVERT([ArtikelID],System.String) Like '*144*' or [Bezeichnung] LIKE '*144*' or [Wert] LIKE '*144*'

    Wie kann ich nun auf diese Bindingsource zugreifen und dann filtern?

    Gruß

    Volker

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Volker Bunge“ ()

    Schalt mal bitte in den Projekteigenschaften bei Kompilieren alle Schalter von keine und Warnung auf Fehler, ggf. abgekürzt durch die dort unten angegebene Funktion Alle Warnungen als Fehler behandeln. Denn die String-zurückgebende Function in Post#1 gibt gar nix zurück. Und solche Unsauberkeiten sollten stets vermieden werden.
    Zum anderen: Du hast dort am Ende eine List(Of Irgendwas), die Du dann dem DGV als DataSource zuweist. Wenn Du diese List klassenweit zwischenspeicherst/verfügbar machst, kannst Du diese mit LINQ wieder filtern, auch eben in anderen Prozeduren.

    Volker Bunge schrieb:

    Da es ja keine eigene Bindingsource hat […] Wie kann ich nun auf diese Bindingsource zugreifen […]
    Du erkennst hoffentlich den Widerspruch.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.
    Hallo VaporiZed,

    vielen Dank für den ersten Hinweis. Alles umgestellt und alle Fehler bereinigt.

    Das mit den Bindingsource ist mir schon klar, dass es eigentlich ein Widerspruch ist. Damit meinte ich auch ehr, dass ich bei meinen Artikeln nur eine Tabelle habe und die hat dann im Form1 auch eine entsprechende ArtikelBindingsource. Diese kann ich somit direkt ansprechen. Mein DGV 2 wird ja über eine LINQ-Abfrage gefüttert und besitzt somit eine solche Bindungsource im Form1 nicht. Das es eine "Art Bindungsource" für das DGV 2 gibt, ist dann auch klar (heißt nur leider nicht so).

    Habe jetzt mal eine Public LINQ_QTV_BS As New BindingSource eingefügt und diese dann so zugewiesen

    VB.NET-Quellcode

    1. DGridView.DataSource = LINQ_Query.ToList
    2. LINQ_QTV_BS.DataSource = LINQ_Query.ToList


    Dann an der Filterstelle folgendes eingefügt

    Suchstring = "EingabemaskeID = 1 and (CONVERT([ArtikelID],System.String) Like '*144*' or [Bezeichnung] LIKE '*144*' or [Wert] LIKE '*144*')"

    VB.NET-Quellcode

    1. LINQ_QTV_BS.Filter = Suchstring
    2. DGridView_TreeView_Suche.DataSource = LINQ_QTV_BS


    (LINQ_QTV_BS soll LinQ Querry TreeView Bindingsource bedeuten, werde ich wenn es läuft auch noch ggf. ändern)

    Wenn ich auf LINQ_QTV_BS gehe und dann in der Liste (der VB.NET-Editor ist hier gemeint), dann bekomme ich auch in der Ergebnisansicht ganz unten alle Daten angezeigt. Leider nicht die, die gefiltert sein sollten.

    Jetzt geht die Suche nach dem berühmten Groschen los. Wo liegt der Fehler?

    LINQ_QTV_BS müsste doch jetzt eine Bindingsource sein und somit das Gleiche sein wie die ArtikelBindingsource. Oder liege ich hier schon falsch?

    Gruß

    Volker
    Ich schrieb ja auch: mit LINQ filtern. Das ist ne andere Filtermethode als mit dem BS-FilterString
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.
    Hallo zusammen,

    @VaporiZed: Mit LINQ filtern geht doch mit der Where Zeile?

    Mit

    VB.NET-Quellcode

    1. For Each tv In LINQ_QTV_BS.List
    2. MessageBox.Show(tv.ToString)
    3. Next


    bekomme ich solche Anzeigen: ArtikelID=1, Bezeichnung="Bahngesellschaft", Wert="DB"
    Im Haltemodus gehe ich dann auf TV und dort steht dann
    ArtikelID |1
    Bezeichnung|"Bahngesellschaft"
    Wert |"DB"

    Somit hat doch die systemweite List-Übernahme in meinen Augen funktioniert.

    Hab dann mal folgendes probiert

    VB.NET-Quellcode

    1. Dim t = From tv In LINQ_QTV_BS.List
    2. Where (tv.wert = "144")
    3. Select tv


    Leider wird TV.Wert als Fehler ausgeworfen.
    Fehler: Option Strict On lässt spätes Binden nicht zu

    Da leider die meisten Beispiele im Netz mit der Add-Methode Beispieldatensätze bilden, ist mir jetzt hier nicht klar, wo der Fehler liegt.

    Gruß

    Volker
    Von welchem Typ ist denn (laut IntelliSense!) LINQ_QTV_BS.List? Und dann kannst Du Dir die Frage stellen, ob der Compiler vor dem Starten des Programms automatisch drauf kommen kann, was dann in der List drinsteht. Oder ob man ihm ggf. noch auf die Sprünge helfen muss.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.
    Hallo VaporiZed,

    ja, Du hast recht, er ist ein Bindingsource und er muss natürlich noch irgendwie umgewandelt werden um dann mit der Where Zeile gefiltert zu werden.

    Da ich in dieser Beziehung leider keine Infos gefunden habe (oder auch falsch gesucht habe), könntest Du mir einen Tipp geben, wo ich die Lösung finden könnte?

    Diesen Link
    docs.microsoft.com/de-de/dotne…ry-an-arraylist-with-linq
    habe ich auch soweit verstanden.

    Aber alle Beispiele erzeugen erst ein paar Testdatensätze und arbeiten damit.

    Dann habe ich es sogar mit der Split - Methode versucht, die Feldnamen und die Werte zu trennen, um somit die Datensätze per Add-Befehl zu erzeugen. Aber leider auch ohne Erfolg. Würde glaube ich selbst dann schwierig werden, da aktuell das Gleichheitszeichen zwischen Feldname und Wert steht, das Komma zwischen den einzelnen Spaltenwerten. Da aber auch die Werte Kommas enthalten können geht diese Methode so nicht, oder wird richtig aufwendig. Glaube sowieso, dass dieser Weg der falsche ist, daher habe ich hier schnell alles wieder gelöscht.

    Es ist leider nicht immer einfach, in den tausenden von Möglichkeiten, Einstellungen und Kniffen den richtigen zu finden bzw. zu erkennen. Gerade wenn es Neuland für einen ist.

    Wäre also super, wenn Du mir einen kleinen Codebrocken geben könntest.

    Gruß

    Volker

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Volker Bunge“ ()

    Volker Bunge schrieb:

    ja, Du hast recht, er ist ein Bindingsource und er muss natürlich noch irgendwie umgewandelt werden
    Hm, nein. Denn meine Frage war: Von welchem Typ ist denn (laut IntelliSense!) LINQ_QTV_BS.List? Dann eben noch die Frage, was Du für einen Typ erwartest. Dann lässt sich das Ganze ggf. casten mit einem Dim DeineTypisiertenEinträge = LINQ_QTV_BS.List.Cast(Of DenTypDenDuGernHättest)
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.
    Wenn ich auf List klicke, bekomme ich diese Anzeige (Bild 1)

    Also müsse das doch so lauten

    Dim DeineTypisiertenEinträge = LINQ_QTV_BS.List.Cast(Of ArrayList)

    damit es am Ende ein ArrayList ist und ich wie im o. g. Link mein LINQ setzen kann

    Wenn ich dann mit

    VB.NET-Quellcode

    1. Public Class TreeViewDaten
    2. Public Property ArtikelID As Integer()
    3. Public Property Bezeichnung As String
    4. Public Property Wert As String
    5. End Class

    VB.NET-Quellcode

    1. Dim t = From tv As TreeViewDaten In DeineTypisiertenEinträge
    2. Where (tv.Wert = "144")
    3. Select tv


    Dann bekomme ich den Fehler
    Schweregrad Code Beschreibung Projekt Datei Zeile Unterdrückungszustand
    Fehler BC30311 Der Wert vom Typ "ArrayList" kann nicht in "Variablendeklarationen.TreeViewDaten" konvertiert werden.


    Bilder
    • Bild1.jpg

      183,28 kB, 1.190×413, 22 mal angesehen

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Volker Bunge“ ()

    Und was passiert, wenn Du nicht .Cast(Of ArrayList) schreibst, sondern .Cast(Of Variablendeklarationen.TreeViewDaten)? Schließlich willst Du keine ArrayList, sondern eine Sammlung von Variablendeklarationen.TreeViewDaten haben und auswerten.
    Und wieso eigentlich Public Property ArtikelID As Integer()? Soll das ein Array sein oder doch lieber ne einzelne Zahl, also Public Property ArtikelID As Integer, eben ohne Klammern am Ende?
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.
    So sieht es es bisher aus

    VB.NET-Quellcode

    1. Dim DeineTypisiertenEinträge = LINQ_QTV_BS.List.Cast(Of Variablendeklarationen.TreeViewDaten)
    2. Dim t = From tv As TreeViewDaten In DeineTypisiertenEinträge
    3. Where (tv.Wert Like "*144*")
    4. Select tv
    5. DGridView_TreeView_Suche.DataSource = t.ToList
    6. Public Class TreeViewDaten
    7. Public Property ArtikelID As Integer
    8. Public Property Bezeichnung As String
    9. Public Property Wert As String
    10. End Class


    Hattest natürlich recht mit dem Integer, habe ich sofort geändert.

    Jetzt kommt es aber in Zeile 7 zu Fehlermeldung

    System.InvalidCastException
    HResult=0x80004002
    Nachricht = Das Objekt des Typs "VB$AnonymousType_6`3[System.Int32,System.String,System.String]" kann nicht in Typ "TreeViewDaten" umgewandelt werden.
    Quelle = System.Core
    Stapelüberwachung:
    bei System.Linq.Enumerable.<CastIterator>d__97`1.MoveNext()
    bei System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
    bei System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) in f:\dd\ndp\clr\src\BCL\system\collections\generic\list.cs: Zeile99
    bei System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
    bei VB_Modelldatenbank.Hauptmaske.Suche_Starten() in R:\VB Modelldatenbank\VB Modelldatenbank\Forms\Hauptmaske.vb: Zeile1320
    bei VB_Modelldatenbank.Hauptmaske.Btn_Suche_Starten_Click(Object sender, EventArgs e) in R:\VB Modelldatenbank\VB Modelldatenbank\Forms\Hauptmaske.vb: Zeile932
    bei System.Windows.Forms.Control.OnClick(EventArgs e)
    bei System.Windows.Forms.Button.OnClick(EventArgs e)
    bei System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
    bei System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
    bei System.Windows.Forms.Control.WndProc(Message& m)
    bei System.Windows.Forms.ButtonBase.WndProc(Message& m)
    bei System.Windows.Forms.Button.WndProc(Message& m)
    bei System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
    bei System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
    bei System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
    bei System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
    bei System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
    bei System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
    bei System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
    bei Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun() in f:\dd\vb\runtime\msvbalib\ApplicationServices\WindowsFormsApplicationBase.vb: Zeile779
    bei Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel() in f:\dd\vb\runtime\msvbalib\ApplicationServices\WindowsFormsApplicationBase.vb: Zeile1471
    bei Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine) in f:\dd\vb\runtime\msvbalib\ApplicationServices\WindowsFormsApplicationBase.vb: Zeile452
    bei VB_Modelldatenbank.My.MyApplication.Main(String[] Args) in : Zeile81

    (Der Originalcode geht von Zeile 1309 bis 1320. 1320 ist somit bei mir die Zeile 7 hier)

    Die drei Eigenschaften, ArtikelID + Bezeichnung + Wert lassen sich super nach der Punktangabe auswählen.

    Was will den VB.Net jetzt schon wieder?

    Gruß

    Volker
    Nun, dann war meine Vermutung falsch. Ich hatte es auch nicht ausprobiert. Für den Compiler sind die Daten erstmal nur eine Gruppe von 3er-Kombis aus Int, String und String. Das könnte man als anonymes 3er-Tupel bezeichnen. Ich würde jetzt direkt aus diesen Tupels Deine Daten erschaffen, also

    VB.NET-Quellcode

    1. Dim TreeViewDatenList As New List(Of TreeViewDaten)
    2. For Each Row In LINQ_QTV_BS.List.Cast(Of (Integer, String, String))
    3. TreeViewDatenList.Add(New TreeViewDaten With {.ArtikelID = Row.Item1, .Bezeichnung = Row.Item2, .Wert = Row.Item3})
    4. Next
    Und dann kannst Du mit TreeViewDatenList normal weiterarbeiten.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.
    Jetzt wirft er bei

    VB.NET-Quellcode

    1. Dim TreeViewDatenList As New List(Of TreeViewDaten)
    2. For Each Row In LINQ_QTV_BS.List.Cast(Of (Integer, String, String))
    3. TreeViewDatenList.Add(New TreeViewDaten With {.ArtikelID = Row.Item1, .Bezeichnung = Row.Item2, .Wert = Row.Item3})
    4. Next
    5. Dim t = From tv As TreeViewDaten In TreeViewDatenList
    6. Where (tv.Wert Like "*144*")
    7. Select tv
    8. DGridView_TreeView_Suche.DataSource = t.ToList



    Zeile 3 4 x Schweregrad Code Beschreibung Projekt Datei Zeile Unterdrückungszustand
    Fehler BC37267 Der vordefinierte Typ "ValueTuple(Of ,,)" wurde nicht definiert oder importiert. VB Modelldatenbank R:\VB Modelldatenbank\VB Modelldatenbank\Forms\Hauptmaske.vb 1303 Aktiv

    Ab LINQ xxx ist alles rot unterstrichen

    (Zeile 1303 ist hier Zeile 3)

    (Habe gerade lt. diesem Link https://intellitect.com/fix-system-valuetuple-error/ das o. g. Problem gelöscht.

    Jetzt hängt er nach dem Starten beim Durchlaufen der Zeilen beim NEXT fest.

    Fehlermeldung
    System.InvalidCastException
    HResult=0x80004002
    Nachricht = Die angegebene Umwandlung ist ungültig.
    Quelle = System.Core
    Stapelüberwachung:
    bei System.Linq.Enumerable.<CastIterator>d__97`1.MoveNext()
    bei VB_Modelldatenbank.Hauptmaske.Suche_Starten() in R:\VB Modelldatenbank\VB Modelldatenbank\Forms\Hauptmaske.vb: Zeile1305
    bei VB_Modelldatenbank.Hauptmaske.Btn_Suche_Starten_Click(Object sender, EventArgs e) in R:\VB Modelldatenbank\VB Modelldatenbank\Forms\Hauptmaske.vb: Zeile932
    bei System.Windows.Forms.Control.OnClick(EventArgs e)
    bei System.Windows.Forms.Button.OnClick(EventArgs e)
    bei System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
    bei System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
    bei System.Windows.Forms.Control.WndProc(Message& m)
    bei System.Windows.Forms.ButtonBase.WndProc(Message& m)
    bei System.Windows.Forms.Button.WndProc(Message& m)
    bei System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
    bei System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
    bei System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
    bei System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
    bei System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
    bei System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
    bei System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
    bei Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun() in f:\dd\vb\runtime\msvbalib\ApplicationServices\WindowsFormsApplicationBase.vb: Zeile779
    bei Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel() in f:\dd\vb\runtime\msvbalib\ApplicationServices\WindowsFormsApplicationBase.vb: Zeile1471
    bei Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine) in f:\dd\vb\runtime\msvbalib\ApplicationServices\WindowsFormsApplicationBase.vb: Zeile452
    bei VB_Modelldatenbank.My.MyApplication.Main(String[] Args) in : Zeile81

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Volker Bunge“ ()

    Du arbeitest mit .NET-Framework 4.0 oder kleiner, richtig? Versuch mal das Ganze auf 4.7 oder 4.8 zu drehen, falls möglich.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.