2010-01-09 1 views
5

У меня есть два типа данных (A, B) с одинаковой структурой. Мне нужно сравнить каждую строку A с буквой B, а результирующий Datatable C должен иметь строку в A и изменения этой строки в B ниже нее. Для строк, которые являются идентичными (те же значения в A & B), в результате Datatable не должен иметь этих строк.Сравнить Datatables & Merge Changes

Таким образом, полученный Datatable должен иметь каждую строку в A и ее неидентичную строку в B под ней. Результирующая таблица не должна иметь одинаковые строки.

Может кто-нибудь, пожалуйста, помогите мне с кодом C#.

+0

Вам нужно сделать это на C# или возможно ли вам использовать инструмент? –

ответ

1

самого простой способ это межбазовый союз:

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

только уникальные строки возвращаются. для сравнения записей, выберите строки, которые используют один и тот же ключ (ключевой столбец в объединенной форме будет не уникальным).

select * from merged order by key 

заказывает результаты в указанном вами порядке.

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

вернет только несоответствующие строки.

+0

Поскольку оба типа данных относятся к различным базам данных, я не могу использовать запросы Sql или Oracle для объединения кросс-баз данных. Есть ли способ достичь этого в C# .net ?? – vinodreddymk

+0

Один из способов - сбросить данные в csv и импортировать его, будет ли самый быстрый способ позволить sql выполнить сравнения – jspcal

+0

Не можем ли мы сравнить 2 datatables и получить желаемый результат вместо того, чтобы сбрасывать данные в csv ?? – vinodreddymk

1

Похоже, вы хотите вычислить symmetric difference двух DataSets. Мы можем сделать это, используя бит LINQ, сравнительный анализатор и несколько методов расширения. Код проверен и работает.

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; 
}