Kleinste gemeinsame Vielfache von einer Spalte zweier Datatables

  • VB.NET

Es gibt 8 Antworten in diesem Thema. Der letzte Beitrag () ist von VB2010 User.

    Kleinste gemeinsame Vielfache von einer Spalte zweier Datatables

    Hallo,

    ich habe zwei Datatables und beide haben eine Spalte mit Kundennummer, ich möchte aber bei einem Datatable die Zeilen entfernen, deren Kundennummer nicht im anderen Datatable vorkommen.

    Die Datatables heißen ds.Tables("Lieferanten") und ds.Tables("Rechnung"). ds.Tables("Lieferanten") soll dann um die Kundennummern "gestutzt" werden die nicht in ds.Tables("Rechnung") vorkommen. Für SQL gibts da den INNER JOIN Befehl.

    Wie kann ich das bei den Datatables machen?
    Du könntest die Einträge in den beiden Datatables anhand einer Schleife durchlaufen und über ein IF-Anweisung prüfen ob die Kundennummer in beiden vorhanden ist wenn nicht einfach die jeweilige Kundennummer löschen!
    Dabei musst du aber darauf achten, das beide Datatables gleich sortiert sind, da sonst zu 80% jeder Eintrag gelöscht wird, weil sie nicht in der gleichen Reihenfolge kommen ;)
    Ja so in der Art mache ich das schon, wenn ich das Datatable befülle:

    VB.NET-Quellcode

    1. While csv.ReadNextRecord
    2. rowVals(0) = csv(0)
    3. rowVals(1) = csv(1)
    4. rowVals(2) = csv(2)
    5. 'Wenn KndNr bei der tblRechnung aufgeführt ist, dann ist ExecuteScalar > 0
    6. cmd = New SqlCommand("SELECT Count(*) FROM tblRechnung WHERE KndNr = @KndNr", con)
    7. cmd.Parameters.AddWithValue("@KndNr", SqlDbType.Int).Value = rowVals(0)
    8. If cmd.ExecuteScalar > 0 Then _
    9. ds.Tables("Lieferanten").Rows.Add(rowVals)
    10. End While


    Das geht mir allerdings viel zu langsam. Wie gesagt eine Art Inner Join Befehl wäre mir lieber, habe schon ds.Merge probiert, aber das liefert nicht das gewünschte Ergebnis.
    Naja das mache ich ja. Ich prüfe mit Count und ExecuteScalar ob die Kundennummer in der DB ist, nur dann füge ich es dem Datatable hinzu.
    Das dauert allerdings zu lange. Ich denke wenn ich die 2 DataSets einfach "Joinen" könnte, würde es deutlich schneller gehen, so kenne ich es zumindest aus Access.
    Ich nutze folgendes SQL-Statement um Daten aus zwei verschiedenen Tabellen zu holen und die Kundennummer mit einander zu vergleichen:

    SQL-Abfrage

    1. SELECT A.TEXT13, A.TEXT2, A.COMPANY1, A.CITY0, A.LASTNAME0, A.FIRSTNAME0, A.EMAIL0, A.ID, B.TEXT1 FROM dbo.ADDRESSES A, dbo.ADDITIONAL B WHERE B.SUPERID=A.ID AND B.TEXT1='" + clsMain.sSelectedProduct + "' AND B.YESNO1 = 'false'"


    Das ganze ist "relativ" schnell und funktioniert ;)
    Was bedeutet für dich langsam?
    Naja wie du im Code erkennst, stammt nur das eine Datatable aus ner SQL Datenbank, das andere kommt aus einer CSV Datei. Sonst könnte ich das natürlich direkt bei der DB als INNER JOIN abfragen.

    Zu lange heißt bei mir: ca. 5 Sekunden. Und das ist viel zu lang bei ca. 2600 Kunden.
    Was ich z.B. auch versucht habe:
    Eine DataRelation:
    Ich kann das allerdings nicht machen:

    VB.NET-Quellcode

    1. Dim lief_rech_Rel As DataRelation = ds.Relations.Add("relKndNr", ds.Tables("Rechnung").Columns("KndNr"), ds.Tables("Lieferanten").Columns("KndNr"))


    Visual Basic kürzt mir hier den Kundennummern nicht weg, der Parenttable fehlen da eben die Kundennummern der Childtable die ich gerne rauswerfen würde.

    Anders herum gehts natürlich:

    VB.NET-Quellcode

    1. Dim lief_rech_Rel As DataRelation = ds.Relations.Add("relKndNr", ds.Tables("Lieferanten").Columns("KndNr"), ds.Tables("Rechnung").Columns("KndNr"))


    Aber dann sind die Kundennummern eben um ein vielfaches in den ChildRows, ich will es gerade anders herum.

    Von der Geschwindigkeit entspricht das auch direkt meinen Wunschvorstellungen, dann dauert das öffnen der CSV und das schreiben der Relation in eine Datatable nur einen Bruchteil einer Sekunde.