2017-03-01 4 views
1

Ich habe zwei DataTables, die Daten von zwei verschiedenen Quellen bekommen. Ich möchte eine neue DataTable-Tabelle3 mit NUR Tables1-Zeilen haben, die nicht übereinstimmende Table2-Zeilen haben. Meine zwei DataTables haben unterschiedliche Strukturen wie unten angegeben. Sie alle teilen jedoch den gleichen Primärschlüssel - CarReg. Daher möchte ich Zeilen mit der CarReg-Spalte vergleichen und alle Zeilen in Tabelle 1, aber NICHT in Tabelle 2 zurückgeben. Meine zurückgegebene Table3 DataTable wird dieselbe Struktur wie Table1 haben.Vergleichen Sie zwei DataTables und wählen Sie erste Tabellensätze aus, die NICHT in der zweiten Tabelle enthalten sind

Table1.Columns.Add("CarReg", typeof(string)); 
Table1.Columns.Add("Site", typeof(string)); 
Table1.Columns.Add("Route", typeof(double)); 
Table1.Columns.Add("Driver", typeof(string)); 
Table1.Columns.Add("StartingDate", typeof(string)); 

Table2.Columns.Add("CarReg", typeof(string)); 
Table2.Columns.Add("SITE DESC", typeof(string)); 
Table2.Columns.Add("Route DESC", typeof(double)); 
Table2.Columns.Add("Driver", typeof(string)); 
Table2.Columns.Add("KILOS", typeof(string)); 

Ich habe versucht, die unten, aber ich bekomme alle Datensätze aus der ersten Tabelle Table1. Ich brauche nur Datensätze, die in Tabelle 1, aber nicht in Tabelle 2 sind. Wenn zum Beispiel Tabelle1 20 Datensätze und Tabellen2 15 Datensätze haben, brauche ich nur die 5 Datensätze. Bitte helfen Sie.

var recordsNotInB = TableA.AsEnumerable().Select(r =>r.Field<string>("CarReg").Except(TableB.AsEnumerable().Select(r => r.Field<string>("CarReg"))); 
+0

Also möchten Sie alle Datensätze aus Tabelle1, die keine übereinstimmende CarReg in Tabelle2 hat? –

+0

@YawarMurtaza Ja, ich möchte alle Datensätze von Table1, die keinen passenden CarReg in Tabelle2 haben. Danke, dass Sie dies in einem einfachen englischen Satz angeben. –

Antwort

1

Ohne mehr von Ihrem Code zu wissen, würde ich mit diesem kommen.

var idsFromTableB = TableB.AsEnumerable().Select(tb => tb.Field<string>("CarReg")); 
var recordsNotInB = TableA.AsEnumerable().Where(ta => !idsFromTableB.Contains(ta.Field<string>("CarReg"))); 
+0

Ich erhalte die gleiche Anzahl von Datensätzen wie das, was ich mit meinem Code bekommen habe, das heißt, ich erhalte alle Datensätze in meiner ersten Tabelle TableA. Ich brauche nur Datensätze in TableA, aber nicht TableB. Ansonsten danke für deine Antwort. –

+0

Danke, ich habe es geschafft, richtig zu kommen. Da ich mich mit einer Stringfeldspalte beschäftigte, musste ich die Werte, die ich an beiden Tabellen erhielt, trimmen, damit sie mit dem Vergleich funktionieren. Vielen Dank noch mal. –

0

Sie können es versuchen, mit dem nächsten Code-Schnipsel:

 var result = new List<DataRow>(); 
     //convert to list to avoid multiple enumerations 
     var table2List = Table2.AsEnumerable().ToList(); 

     foreach(var row in Table1.AsEnumerable()) 
     { 
      var matchingRow = table2List.FirstOrDefault(x => x["CarReg"] == row["CarReg"]); 

      if(matchingRow == null) 
      { 
       result.Add(row); 
      } 
     } 

Sie sollen Sammlung von DataRows von Tabelle 1 erhalten, die nicht in Tabelle 2 sind basierend auf carreg Feld.

+0

Das funktioniert nicht für mich.Dieser Code liefert tatsächlich noch mehr Datensätze - so etwas wie ein kartesisches Produkt. Zur Verdeutlichung haben sowohl Tabelle 1 als auch Tabelle 2 dieselbe Primärstruktur. Daher wird ein Datensatz in Tabelle1 nur einmal in Tabelle2 vorkommen, wenn er dort vorhanden ist. Also, in meinem Fall möchte ich alle Datensätze, die derzeit in Tabelle1 sind, aber die Datensätze (wegen des Primärschlüssels "CarReg") sind noch nicht in Tabelle2 –

+0

Ich fügte Änderungen hinzu, die in der Lage sein sollten, die Aufgabe zu erfüllen, die Sie angefordert haben. –

1

Sie können die Leistung verbessern und auch die Vergleichsmethode mithilfe eines Hash-Satzes angeben.

var idsFromTableB = new HashSet<string>(TableB.AsEnumerable() 
    .Select(tb => tb.Field<string>("CarReg")), StringComparer.OrdinalIgnoreCase); 

var recordsNotInB = TableA.AsEnumerable() 
    .Where(ta => !idsFromTableB.Contains(ta.Field<string>("CarReg"))); 
0

Okay, das ist eine langatmige Lösung, aber ich habe es getestet und es funktioniert.

Ich habe es getan, indem ich POCO-Objekte für jede Tabelle erstellt habe, dann die Unterschiede, da es einfacher ist, mit öffentlichen Eigenschaften zu spielen als mit Table1 ["CarReg"], das anfällig für Fehler ist.

Möglicherweise kann jemand diese Lösung verbessern.

Ihre Tabellen Lassen Sie durch POCO-Klassen wie dargestellt werden:

public class Table1 
{ 
    public string CarReg { get; set; } 
    public string Site { get; set; } 
    public double Route { get; set; } 
    public string Driver { get; set; } 
    public string DateString { get; set; } 
} 

public class Table2 
{ 
    public string CarReg { get; set; } 
    public string Site { get; set; } 
    public double Route { get; set; } 
    public string Driver { get; set; } 
    public string Kilos { get; set; } 
} 

Läßt die Daten füllen:

IEnumerable<Table1> data1 = new List<Table1>() 
      { 
       new Table1() { CarReg = "123ABC", DateString = "20/02/2018", Driver = "Driver 1", Route = 45.45, Site = "England" }, 
       new Table1() { CarReg = "456ABC", DateString = "20/03/2018", Driver = "Driver 2", Route = 55.45, Site = "Scotland" }, 
       new Table1() { CarReg = "789ABC", DateString = "20/04/2018", Driver = "Driver 3", Route = 65.45, Site = "Wales" }, 
      }; 

      IEnumerable<Table2> data2 = new List<Table2>() { 
       new Table2() { CarReg = "123XYZ", Kilos = "34KG", Driver = "Driver 5", Route = 45.45, Site = "Karachi" }, 
       new Table2() { CarReg = "456ABC", Kilos = "44KG", Driver = "Driver 2", Route = 55.45, Site = "Scotland" }, 
       new Table2() { CarReg = "789CCC", Kilos = "54KG", Driver = "Driver 7", Route = 65.45, Site = "Hyderabad" }, 
      }; 

Erstellen Sie eine Liste der Ergebnisdaten zu halten:

List<Table1> oneList = new List<Table1>(); 

Durchlaufen, um die Zeilen zu identifizieren, die nicht in Tabelle 2 enthalten sind

bool matchFound = false; // an indicator if match is found in table 2 

     foreach (var item in data1) 
     { 
      foreach (var item2 in data2) 
      { 
       if (item.CarReg != item2.CarReg) 
       { 
        matchFound = false; 
       } 
       else 
       { 
        matchFound = true; 
        break; 
       } 
      } 
      if (!matchFound) 
      { 
       if (!oneList.Contains(item)) 
       { 
        oneList.Add(item); 
       } 
      } 

     } 

Hoffe diese Hilfe!

Verwandte Themen