Entwickler-Ecke

Basistechnologien - Doppeleinträge löschen


dinazavric - Fr 29.04.11 14:03
Titel: Doppeleinträge löschen
Im Internet habe ich ein Beispiel gefunden wie ich anhand von Hashtable die doppelten Einträge aus einer DataTable löschen kann.


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
            Hashtable hashTable1 = new Hashtable();
            string columnName1 = "ProtocolID";
            List<DataRow> duplicateList1 = new List<DataRow>();

            foreach (DataRow dataRow in dataSetPro.Tables["Protocols"].Rows)
                try
                {
                    hashTable1.Add(dataRow[columnName1], string.Empty);
                }
                catch
                {
                    duplicateList1.Add(dataRow);
                }
            foreach (DataRow dataRow in duplicateList1)
                dataSetPro.Tables["Protocols"].Rows.Remove(dataRow);


Ich habe ein DataSet mit zwei DataTables und möchte nicht nur anhand von einem Element die Daten löschen, wie es im Code oben gemacht wurde. Das würde gehen, wenn ich nur zwei Spalten habe. Das gilt bei mir eben nür für eine Tabelle. Die andere beinhaltet Parameter, die die einzelnen Protocole aus der ersten Tabelle beschreiben. In dem Fall möchte ich nicht nur die Einträge aus der zweiten Tabelle löschen, die gleiche IDs haben, da es durchaus möglich ist, sondern nur die, die kommplet gleich sind oder sich nur in der dritten Zeile unterscheiden. Hier ein Beispiel:

Table Protocols:
p1
p2
p3

Table Parameters
p1 n1 12
p1 n2 33
p1 n2 33
p2 n1 11
p3 n2 12
p3 n2 10

In diesem Beispiel solltel die Zeilen 3 und 6 gelöscht werden, da sie entweder gleich sind oder den gleichen Parameter (hier n2) mit zwei Values (hier 12 und 10) beschreiben. Beim letzten Eintrag soll der ältere Eintrag gelöscht werden. Wie kann man sowas realisieren?


IsNull - Fr 29.04.11 14:22

Nutze Distinct(), dem du einen custom EqualityComparer spendierst.
Der EqualityComparer muss dann einfach die ersten beiden Spalten (Felder) vergleichen, da das dritte Feld ja unterschiedlich sein darf.


Yogu - Fr 29.04.11 15:35

Wäre nett, wenn du den Crosspost aus myCSharp.de [http://www.mycsharp.de/wbb2/thread.php?threadid=95168] wenigstens verlinken würdest.


dinazavric - Fr 29.04.11 15:36

user profile iconYogu hat folgendes geschrieben Zum zitierten Posting springen:
Wäre nett, wenn du den Crosspost aus myCSharp.de [http://www.mycsharp.de/wbb2/thread.php?threadid=95168] wenigstens verlinken würdest.


OK :-)


dinazavric - Mo 02.05.11 09:35

user profile iconIsNull hat folgendes geschrieben Zum zitierten Posting springen:
Nutze Distinct(), dem du einen custom EqualityComparer spendierst.
Der EqualityComparer muss dann einfach die ersten beiden Spalten (Felder) vergleichen, da das dritte Feld ja unterschiedlich sein darf.


So wie ich verstanden habe, kann man Distinct() nicht direct für DataSets, bzw. DataTables benutzen, sondern das ganze über Arrays programmieren?


Ralf Jansen - Mo 02.05.11 10:02

Nein. Linq To Dataset [http://msdn.microsoft.com/de-de/library/bb386977.aspx]


dinazavric - Mo 02.05.11 10:38

Ich habe keine Datenbank o.Ä., ich benutze ein nicht typisiertes DataSet mit wenig Daten. Wäre es mit LINQ to DataSet nicht etwas zu groß für so eine Aufgabe? Gibt es nicht etwas Ähnliches wie Distinct() für DataTables? Alle Beispiele, die ich im Internet gefunden habe machen eine Suche in einer DataTable und erstellen dann eine neue mit den Zeilen, die ein Feld gleich haben. Ich möchte aber aus meiner Tabelle die Zeilen löschen, die zwei Felder aus drei gleich haben.


dinazavric - Mo 02.05.11 10:52

Ich habe jetzt ein Beispiel gefunden, das mir, meiner Meinung nach, mit meinem Problem weiter helfen könnte. Nur habe ich etwas Schwierigkeiten diesen Code auf Sucher für gleichzeitig zwei Felder zu erweitern und ganau diese Zeilen aus meiner bestehenden DataTable zu löschen. Kann mir da jemand helfen? Hier ist der Code dazu:



C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
public static DataTable GetDistinct(string table, DataTable source, string field)
{
    //new DataTable to hold the distinct values
    DataTable newDT = new DataTable(table);

    //add a new column to the DataTable (column we are searching in)
    newDT.Columns.Add(field, source.Columns[field].DataType);

    //get an array of DataRows that match the search criteria
    DataRow[] rows = source.Select("", field);

    object value = null;

    //loop through all the rows
    foreach (DataRow row in rows)
    {
        if (value == null || !(AreEqual(value, row[field])))
        {
            value = row[field];
            newDT.Rows.Add(new object[] { value });
        }
    }
    return newDT;
}

private static bool AreEqual(object obj1, object obj2)
{
    //both columns are DBNull.Value
    if (object.ReferenceEquals(obj1, DBNull.Value) & object.ReferenceEquals(obj2, DBNull.Value))
        return true;
    //only one column is DBNull.Value
    if (object.ReferenceEquals(obj1, DBNull.Value) | object.ReferenceEquals(obj2, DBNull.Value))
        return false;

    //if we make it this far then we just do a standard comparison
    return obj1 == obj2;
}