2010-01-09 16 views
5

Ich habe zwei Databases (A, B) mit der gleichen Struktur. Ich muss jede Zeile von A mit der von B vergleichen und die resultierende Datatable C sollte die Zeile in A und die Änderungen dieser Zeile in B darunter haben. Bei identischen Zeilen (gleiche Werte in A & B) sollte das resultierende Datatable diese Zeilen nicht enthalten.Vergleichen von Databases & Zusammenführungsänderungen

Also die resultierende Datatable sollte jede Zeile in A und seine nicht identische Zeile in B darunter haben. Die resultierende Tabelle sollte keine identischen Zeilen enthalten.

Kann mir bitte jemand helfen mit C# -Code.

+0

Müssen Sie es in C# tun oder ist es möglich, ein Werkzeug zu verwenden? –

Antwort

1

der einfachste Weg ist eine Quer Datenbank Vereinigung:

create table merged 
(select * from db1.t) union (select * from db2.t) 

nur eindeutige Zeilen zurückgegeben werden. Um Datensätze zu vergleichen, wählen Sie Zeilen mit demselben Schlüssel aus (die Schlüsselspalte in der Zusammenführung ist nicht eindeutig).

select * from merged order by key 

bestellt die Ergebnisse in der von Ihnen gewünschten Reihenfolge.

select * from merged where key in 
(select key from merged group by key having count(*) > 1) 
order by key 

wird nur nicht übereinstimmende Zeilen zurückgeben.

+0

Da beide Databases aus verschiedenen Datenbanken stammen, kann ich keine Sql- oder Oracle-Abfragen für eine datenbankübergreifende Verbindung verwenden. Gibt es eine Möglichkeit, dies in C# zu erreichen? – vinodreddymk

+0

eine Möglichkeit ist, die Daten zu csv zu dumpen und es zu importieren, wäre am schnellsten zu lassen sql die Vergleiche – jspcal

+0

Kann man nicht direkt 2 Databases vergleichen und das gewünschte Ergebnis erhalten, anstatt die Daten in eine csv dumping? – vinodreddymk

1

Es sieht so aus, als ob Sie die symmetric difference von zwei DataSets berechnen möchten. Wir können dies tun, indem wir ein bisschen LINQ, einen Gleichheitsvergleich und einige Erweiterungsmethoden verwenden. Der Code ist getestet und funktioniert.

class Program 
{ 
    static void Main() 
    { 
     var a = new DataTable {Columns = {{"FirstName", typeof (string)}, {"Age", typeof (int)}}, Rows = {{"Alice", 31}, {"Bob", 42}}}; 
     var b = new DataTable {Columns = {{"FirstName", typeof (string)}, {"Age", typeof (int)}}, Rows = {{"Alice", 31}, {"Carol", 53}}}; 
     var diffs = a.SymmetricDifference(b); 
     Console.Write(diffs.Rows.Count); 
    } 
} 

public static class DataTableExtensions 
{ 
    public static DataTable SymmetricDifference(this DataTable a, DataTable b) 
    { 
     var diff = a.Clone(); 
     foreach (var person in a.AsPersonList().SymmetricDifference(b.AsPersonList())) 
     { 
      diff.Rows.Add(person.FirstName, person.Age); 
     } 

     return diff; 
    } 

    private static IEnumerable<Person> SymmetricDifference(this IEnumerable<Person> a, IEnumerable<Person> b) 
    { 
     return a.SymmetricDifference(b, new PersonComparer()); 
    } 

    private static IEnumerable<T> SymmetricDifference<T>(this IEnumerable<T> a, IEnumerable<T> b, IEqualityComparer<T> comparer) 
    { 
     return a.Except(b, comparer).Concat(b.Except(a, comparer)); 
    } 

    private static IEnumerable<Person> AsPersonList(this DataTable table) 
    { 
     return table.AsEnumerable().Select(row => row.AsPerson()).ToList(); 
    } 

    private static Person AsPerson(this DataRow row) 
    { 
     return new Person 
        { 
         FirstName = row.Field<string>("FirstName"), 
         Age = row.Field<int>("Age") 
        }; 
    } 
} 

public class PersonComparer : IEqualityComparer<Person> 
{ 
    public bool Equals(Person a, Person b) 
    { 
     return a.FirstName == b.FirstName && a.Age == b.Age; 
    } 

    public int GetHashCode(Person item) 
    { 
     return StringComparer.InvariantCultureIgnoreCase.GetHashCode(item.FirstName) 
       + StringComparer.InvariantCultureIgnoreCase.GetHashCode(item.Age); 
    } 
} 

public class Person 
{ 
    public string FirstName; 
    public int Age; 
}