Linq - Group Join - Synatax Probleme

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

Es gibt 160 Antworten in diesem Thema. Der letzte Beitrag () ist von StGo.

    StGo aus Post #12 schrieb:

    Ja sehe den Fehler. Habe es aber nur falsch übertragen im Code stimmt die Zuordnung.
    "Where tB.IDTabelleA = tA.ID And tC.IDTabelleA = tA.ID"

    ...also mit And schließen sich beide Argumente gegeneinander aus und bringen keine Ergebnisse, mit Or schon - aber da kann man den Where-Abschnitt gleich weglassen.
    Ich habe es jetzt so versucht:

    VB.NET-Quellcode

    1. Dim q1 = From a In dts.TabelleA Join b In dts.TabelleB On a.Id Equals b.IdTabelleA
    2. Select New With {.id = a.Id, .sp1 = a.Spalte2, .sp2 = a.Spalte3, .B = b.bSpalte, .C = ""}
    3. Dim q2 = From a In dts.TabelleA Join c In dts.TabelleC On a.Id Equals c.IdTabelleA
    4. Select New With {.id = a.Id, .sp1 = a.Spalte2, .sp2 = a.Spalte3, .B = "", .C = c.cSpalte}
    5. Dim Result = q1.Concat(q2)

    Edit: Das bezieht sich natürlich auf das Datenmaterial von Post #1

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

    Ich habe mich mal ein wenig daran gesetzt: warum Join/Group, wenn du die LINQ auch so nutzen kannst?

    C#-Quellcode

    1. var stammRow1 = dataSet1.Stammdaten.AddStammdatenRow("Test", "Test", "Test");
    2. var stammRow2 = dataSet1.Stammdaten.AddStammdatenRow("Test2", "Test2", "Test");
    3. var pdfRow1 = dataSet1.PDF.AddPDFRow("Test", stammRow1);
    4. var pdfRow2 = dataSet1.PDF.AddPDFRow("Test2", stammRow1);
    5. var pdfRow3 = dataSet1.PDF.AddPDFRow("Test3", stammRow2);
    6. var xlsRow1 = dataSet1.XLS.AddXLSRow("Test1", "A2", stammRow1);
    7. var xlsRow2 = dataSet1.XLS.AddXLSRow("Test2", "A2", stammRow2);
    8. var xlsRow3 = dataSet1.XLS.AddXLSRow("Test3", "B2", stammRow2);
    9. dataSet1.AcceptChanges();
    10. dataSet1BindingSource.DataSource = from stammdata in dataSet1.Stammdaten
    11. from pdf in dataSet1.PDF
    12. from xls in dataSet1.XLS
    13. where stammdata.Id == pdf.IdStammdaten && stammdata.Id == xls.IdStammdaten
    14. select new { Id = stammdata.Id, Bereich = pdf.Bereich, Sheet = xls.Sheet, Zelle = xls.Zelle };

    Basierend auf dem Screenshot habe ich auch ein Beispielprojekt aufgebaut, was genau das macht, was du versuchst zu erreichen. (Visual Studio 2012 Express oder neuer erforderlich)
    Dateien

    VB1963 schrieb:

    ...also mit And schließen sich beide Argumente gegeneinander aus und bringen keine Ergebnisse, mit Or schon - aber da kann man den Where-Abschnitt gleich weglassen.
    Ich habe es jetzt so versucht:



    Eben nicht. Der FK von TabelleB ist der Primärschlüssel von TabelleA und der FK von TabelleC ist der Primär von TabelleB

    Mit dem "AND" verknüpfe ich komplett richtig indem ich sagen

    Ich möchte nur ergebnisse WO FK von B = Primär von A (und jetzt pass auf) UND FK von C = Primär von B


    klingt logisch oder?
    ich hab jetzt AliveDevils Lösung angeguckt, und die Entsprechung mit Join gecodet:

    C#-Quellcode

    1. public Form1()
    2. {
    3. InitializeComponent();
    4. var stammRow1 = dataSet1.Stammdaten.AddStammdatenRow("Test", "Test", "Test");
    5. var stammRow2 = dataSet1.Stammdaten.AddStammdatenRow("Test2", "Test2", "Test");
    6. var pdfRow1 = dataSet1.PDF.AddPDFRow("Test", stammRow1);
    7. var pdfRow2 = dataSet1.PDF.AddPDFRow("Test2", stammRow1);
    8. var pdfRow3 = dataSet1.PDF.AddPDFRow("Test3", stammRow2);
    9. var xlsRow1 = dataSet1.XLS.AddXLSRow("Test1", "A2", stammRow1);
    10. var xlsRow2 = dataSet1.XLS.AddXLSRow("Test2", "A2", stammRow2);
    11. var xlsRow3 = dataSet1.XLS.AddXLSRow("Test3", "B2", stammRow2);
    12. dataSet1.AcceptChanges();
    13. dataGridView1.AutoGenerateColumns = true;
    14. var data = from stammdata in dataSet1.Stammdaten
    15. join pdf in dataSet1.PDF on stammdata.Id equals pdf.IdStammdaten
    16. join xls in dataSet1.XLS on stammdata.Id equals xls.IdStammdaten
    17. select new { Id = stammdata.Id, Bereich = pdf.Bereich, Sheet = xls.Sheet, Zelle = xls.Zelle };
    18. data = from stammdata in dataSet1.Stammdaten
    19. from pdf in dataSet1.PDF
    20. from xls in dataSet1.XLS
    21. where stammdata.Id == pdf.IdStammdaten && stammdata.Id == xls.IdStammdaten
    22. select new { Id = stammdata.Id, Bereich = pdf.Bereich, Sheet = xls.Sheet, Zelle = xls.Zelle };
    23. dataSet1BindingSource.DataSource = data.ToList();
    24. }
    Man bekommt dieselben Daten zu sehen:
    Wenn zeile#26 so bleibt greift AliveDevils Lösung, verschiebt man #26 auf #19, so greift die joining-Lösung.
    Morgen zusammen,

    danke für die zahlreiche Hilfe. Bei meinen Lösungsversuchen waren ähnlich Lösungen dabei. Ein Fehler den ich gemacht habe ist die neue Tabelle nicht richtig anzulegen. Ich dachte, dass die Spaltenbezeichnungen aus den original Tabllen übernommen werden.

    Habe Code von AliveDevil ausprobiert und den von EDR. Beide erzeugen eine neue Tabelle allerdings ohne Inhalt. Wo der verloren geht werde ich noch herausfinden.

    Falls jemand das "Ergebnis" in vb sehen möchte:

    VB.NET-Quellcode

    1. Public Class mrfTest1
    2. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    3. Dim dsStammdaten As New DataSetStammdatenDB
    4. Dim taStammdaten As New DataSetStammdatenDBTableAdapters.StammdatenTableAdapter
    5. Dim taXls As New DataSetStammdatenDBTableAdapters.XLSTableAdapter
    6. Dim taPdf As New DataSetStammdatenDBTableAdapters.PDFTableAdapter
    7. taStammdaten.Fill(dsStammdaten.Stammdaten)
    8. taXls.Fill(dsStammdaten.XLS)
    9. taPdf.Fill(dsStammdaten.PDF)
    10. Dim q = From s In dsStammdaten.Stammdaten _
    11. Join p In dsStammdaten.PDF On s.Id Equals p.IdStammdaten _
    12. Join x In dsStammdaten.XLS On s.Id Equals x.IdStammdaten _
    13. Select New With {.Id = s.Id, .Eingabepfad = s.Eingabepfad, .Ausgabepfad = s.Ausgabepfad, .Sheet = x.Sheet, .Zelle = x.Zelle, .Bereich = p.Bereich}
    14. Dim q1 = From s In dsStammdaten.Stammdaten _
    15. From p In dsStammdaten.PDF _
    16. From x In dsStammdaten.XLS _
    17. Where s.Id = p.IdStammdaten And s.Id = x.IdStammdaten _
    18. Select New With {.Id = s.Id, .Eingabepfad = s.Eingabepfad, .Ausgabepfad = s.Ausgabepfad, .Sheet = x.Sheet, .Zelle = x.Zelle, .Bereich = p.Bereich}
    19. Me.DataGridView1.DataSource = q1.ToList
    20. End Sub
    21. End Class


    Ich hänge das Projekt mal dran. Der aktuelle Code findet sich in TypisiertesDataSetTest1. Ich spiele in dem Projekt etwas mit den verschieden Ansichten.

    Dim q1 = From a In dts.TabelleA Join b In dts.TabelleB On a.Id Equals b.IdTabelleA
    Select New With {.id = a.Id, .sp1 = a.Spalte2, .sp2 = a.Spalte3, .B = b.bSpalte, .C = ""}
    Dim q2 = From a In dts.TabelleA Join c In dts.TabelleC On a.Id Equals c.IdTabelleA
    Select New With {.id = a.Id, .sp1 = a.Spalte2, .sp2 = a.Spalte3, .B = "", .C = c.cSpalte}
    Dim Result = q1.Concat(q2)


    Das habe ich auch schon probiert. Leider mit dem gleichen Ergebnis das nichts dabei raus kam. Habe auch probiert mit Union die beiden Kindtabellen zu verbinden und dann zu joinen. War leider auch nichts.

    Dateien

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

    VB1963 schrieb:

    shaebich schrieb:

    klingt logisch oder?
    ...also bei mir kommen keine Ergebnisse dabei heraus?


    Also bei mir hat es ohne Probleme funktioniert. Man muss natürlich auch das DataSet so aufbauen. Der Code war natürlich nicht allgemein, er sollte nur als idee fungieren. Man kann einen Join ohne Probleme mit der WHERE Klausel nachbauen.
    Auf Grundlage des Datenmaterials von Post #1
    TabelleA:
    Id | spalte2 | spalte3
    1 | test | test
    2 | test2 | test2

    TablleB:
    Id | IdTabelleA |bSpalte
    1 | 1 | testB

    TabelleC:
    Id | IdTabelleA | cSpalte
    1 | 2 | testC
    geht's nicht...

    Ergebnis sollte sein:
    Id (aus TabelleA) | spalte2 | spalte3 | bSpalte | cSpalte
    1 | test | test |testB | -
    2 | test2 | test2 | - | testC

    shaebich schrieb:

    Man kann einen Join ohne Probleme mit der WHERE Klausel nachbauen.
    ist aber i.a. keine gute Idee, denn ein Join 3er Tabellen ist glaub wesentlich effizienter als das kartesisches Produkt 3er Tabellen mittels Where auszusieben.

    Glaub ich zumindest - Benchmarks hab ich noch nicht gemacht. Aber wäre auch von daher logisch, dass man sich sonst fragen müsste, wozu Join überhaupt nötig ist.

    StGo schrieb:

    Aber trotzdem bekomme ich keine Ausgabe. Ich vermute eher das ich was in Richtung bindingSource machen muss. Da lese ich noch dran.



    Erst einmal liegt es daran, dass du dein DataSet komplett Falsch befüllst...

    Kp was du da im FormLoad versuchst zu tun, aber so funktioniert es nicht.

    Du benötigst lediglich 3 Zeilen und die sind:

    VB.NET-Quellcode

    1. Me.StammdatenTableAdapter.Fill(DataSetStammdatenDB.Stammdaten)
    2. Me.PDFTableAdapter.Fill(DataSetStammdatenDB.PDF)
    3. Me.XLSTableAdapter.Fill(DataSetStammdatenDB.XLS)


    Dannach ist dein DataSet voll...

    Was du da allerding versuchst anzuzeigen, kann ich dir nicht genau sagen, ob dies funktioniert, da deine Tabelle unterschiedlich sind und ich soetwas noch nie mit linq realisieren musste.
    na, die 3 Zeilen hat er doch. Nur nimmt er unsinnigerweise nicht die TableAdapter, die der FormDesigner generiert hat, sondern er instanziert neue (und disposed die nicht wieder).
    Aber funzen oder nicht funzen tut das ebenso wie deine 3 Zeilen

    AliveDevil sei dank haben wir eine brauchbare Sample-Solution, auf der man reproduzierbare Experimente entwickeln kann :thumbup:
    Aussagen zu allem anneren sind imo eher Spekulation.

    StGo schrieb:

    Wo der verloren geht werde ich noch herausfinden.


    ErfinderDesRades schrieb:

    na, die 3 Zeilen hat er doch. Nur nimmt er unsinnigerweise nicht die TableAdapter, die der FormDesigner generiert hat, sondern er instanziert neue (und disposed die nicht wieder).
    Aber funzen oder nicht funzen tut das ebenso wie dein Code-Vorschlag.



    Also bei mir bleibt jegliche Anzeige leer so wie es im FormLoad ist :D
    Ich hatte die vom ForumDesigner produzierten TableAdapter im laufe des Testens gelöscht. Inzwischen sind sie wieder an Ort und Stelle und die anderen sind gelöscht.

    ich hänge gerne das Projekt nochmal an.


    Also bei mir bleibt jegliche Anzeige leer so wie es im FormLoad ist


    Wenn du den Kommentar von diesem Codeabschnitt nimmst bekommst du die Stammdaten mit XLS gejoint und angezeigt auch mit den "falschen" TableAdaptern:

    VB.NET-Quellcode

    1. Dim q = From s In dsStammdaten.Stammdaten _
    2. Join x In dsStammdaten.XLS _
    3. On s.Id Equals x.IdStammdaten _
    4. Select New With {s.Id, s.Eingabepfad, s.Ausgabepfad, x.Sheet, x.Zelle}



    Danke
    Dateien
    ups - übersehen!

    aber nützt nix - bei mir failt schon die Connection. Erstmal eh, denn LocalDb kennt mein System nicht als DB-Server, aber auch bei angepasst auf mein System erhalte ich:

    Fehler schrieb:

    Fehler beim Anfügen einer automatisch benannten Datenbank für die Datei C:\Users\Account1\Downloads\TypisiertesDataSet\TypisiertesDataSet2\TypisiertesDataSetTest1\bin\Debug\StammdatenDB.mdf. Eine Datenbank mit diesem Namen ist bereits vorhanden, die angegebene Datei kann nicht geöffnet werden, oder sie befindet sich in der UNC-Freigabe.