2016-09-30 4 views
0

Ich bin neu in der Codierung und versuche, eine Tabelle für doppelte Zeilen zu überprüfen. Die Tabelle hat 50 Spalten und jede Spalte muss mit Ausnahme von zwei Spalten verglichen werden. Wenn die Zeilen dupliziert sind, werden sie zu einer Zeile kombiniert und die Beträge in den Spalten REQNUM und AUTHNUM werden addiert. Die meisten der Stichproben, die ich gefunden habe, verwenden "Feld (" ein Spaltenname ")". Wegen der großen Anzahl von Spalten möchte ich eine Variable verwenden, die die beiden, die ich nicht benötige, im Vergleich ausschließt.Duplikate in einer Datentabelle mit mehreren Spalten außer zwei finden

Beispiel:
Vorher. Die Punkte stellen mehr Spalten dar.
COL1 | COL2 | COL3 | ... | REQNUM | AUTHNUM
: -----: | : -----: | : ----: | ... | : ----------: | : -----------: | ....
x | y | z | ... | 1 | 1
x | y | z | ... | 2 | 3

Nach
COL1 | COL2 | COL3 | ... | REQNUM | AUTHNUM
------- | ------ | ------ | ... | ------------ | ------------ | ....
x | y | z | ... | 3 | 4

Dies ist der Code, den ich habe und es scheint nah, aber nicht ganz richtig. Ich habe ein Ergebnis von nur doppelten Zeilen erwartet, also kann ich es später durch eine Foreach ausführen, die zusätzliche Zeilen summiert und löscht. dtrow holt mir die Spalten, die ich will. (Danke an Linq Excluding a column). Wenn ich versuche, die Variable in meiner Abfrage zu verwenden, erhalte ich keine Ergebnisse und wenn ich "g.Count()> 1" entferne, bekomme ich alle Zeilen, in denen die beiden Spalten fehlen. Ich möchte die beiden Spalten in den Ergebnissen behalten und sie später nicht mehr hinzufügen.

 var dtRow = dtExcel.Columns.Cast<DataColumn>().Where(c => c.ColumnName != "REQNUM" && c.ColumnName != "AUTHNUM").ToList(); 

     var checkExcel = dtExcel.Rows.Cast<DataRow>() 
      .GroupBy(x => dtRow.Select(c => x[c])) 
      .Where(g => g.Count() > 1) 
      .Select(gr => gr); 
     //.CopyToDataTable(); 

Vielen Dank für Hilfe. Dies funktionierte großartig für das, was ich brauchte. Ich habe die groupby-Klausel verwendet, damit ich das Duplikat zu einer Zeile kombinieren und die Zahlenfelder hinzufügen kann. Gruppieren Sie auch, indem Sie einen Schlüssel erstellen, den ich in einer IF-Anweisung verwende.

Ich habe auch eine WHERE-Klausel verwendet, um eine Variable für Datarow vergleichen und keinen Schlüssel benötigt. // Erstellt eine Variable mit allen Spalten außer drei. Es wird in der nächsten Abfrage verwendet var dtExcelRow = dtExcel.Columns .Cast(). Wo (c => c.ColumnName! = "TITEL" & & c.ColumnName! = "REQSTR" & & c.ColumnName! = " AUTHSTR "). ToList(); var dtListRow = dtList.Columns .Cast(). Wo (c => c.ColumnName! = "TITEL" & & c.ColumnName! = "REQSTR" & & c.ColumnName! = "AUTHSTR"). ToList ();

  // Querys create datarow list for compare 
      IEnumerable<DataRow> eRow = dtExcel.AsEnumerable() 
       .Where(w => dtExcelRow.Select(c => w[c]).Any()) 
       .Select(x => x); 
      IEnumerable<DataRow> lRow = dtList.AsEnumerable() 
       .Where(w => dtListRow.Select(c => w[c]).Any()) 
       .Select(x => x); 

      // 1st compare gets list of new records that have changes or are new. 2nd is list of old records being change. 
      var newRecords = eRow.AsEnumerable().Except(lRow.AsEnumerable(), DataRowComparer.Default); 
      var oldRecords = lRow.AsEnumerable().Except(eRow.AsEnumerable(), DataRowComparer.Default); 
+0

Dank Ken das ist, was ich kam mit und es große Arbeit für das, was ich brauchte. – fmrjrhd

+0

var dtRow = dtExcel.Columns.Cast (). Wo (c => c.ColumnName! = "REQNUM" && c.ColumnName! = "AUTHNUM"). ToList(); var excelDup = dtExcel.Rows.Guss () .GroupBy (x => String.Join ("", dtRow.Select (c => x [c]))) .Select (g => { var row = g.First() ; row.SetField ("REQSTR", g.Sum (x => x.Feld ("REQSTR"))); row.SetField ("AUTHNUM", g.Sum (x => x.Feld ("AUTHNUM"))); return row; }). CopyToDataTable(); – fmrjrhd

Antwort

0

Sie können nicht Gruppe nur die Daten von dtRow.Select(c => x[c]), weil es ein IEnumerable ist, können sie den gleichen Inhalt haben, aber sie sind immer noch unterschiedliche IEnumerable.

Wenn sie string, Sie können Gruppe die Daten von dem verbundenen string:

x => String.Join("", dtRow.Select(c => x[c])) 
+0

Danke Ken. Dies brachte mir ein Ergebnis der Zeilen in einer langen Zeichenfolge und fehlte immer noch die Spalten REQNUM und AUTHNUM. Ich denke, ich brauche die Zeilen, um ein IEnumerable zu bleiben, damit ich die Spalten REQNUM und AUTHNUM der doppelten Zeile summieren kann. Sehe ich die Abfrage falsch? Gruppieren nach, um Zeilen zu erhalten, die auf Spalten übereinstimmen, wählen Sie dann aus, wo Gruppen mehr als eine Zeile haben. – fmrjrhd

+0

Ich bin mir nicht sicher, was du meinst. Die lange Zeichenfolge sollte nur als Gruppierungsschlüssel verwendet werden, so dass 'g.Key' eine Zeichenfolge ist. Daher sollten die Spalten REQNUM und AUTHNUM nicht fehlen, die Abfrageergebnisse sind immer noch 'IEnumerable'. –

+0

Danke für die Antwort Ken. Ich habe die Gruppe so gehalten, wie Sie es erwähnt haben, und meine Auswahl geändert, und das hat das Problem korrigiert. Ich habe den neuen Code mit meiner ursprünglichen Frage. Danke nochmal für Hilfe. – fmrjrhd

Verwandte Themen