2010-01-09 155 views
5

我有兩個具有相同結構的數據表(A,B)。我需要將A的每一行與B的行進行比較,並且生成的數據表C應該具有A中的行以及B下面的該行中的變化。對於相同的行(A & B中的值相同),生成的Datatable不應包含這些行。比較數據表和合並更改

所以生成的Datatable應該有A中的每一行和它下面B中的不相同的行。結果表格不應該有相同的行。

任何人都可以請幫我用C#代碼。

+0

您是否需要在C#中使用它,或者您可以使用工具嗎? – 2010-01-12 11:14:15

回答

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 2010-01-09 05:38:20

+0

一種方法是將數據轉儲到csv並導入它,將最快讓sql做比較 – jspcal 2010-01-09 05:58:00

+0

我們不能直接比較2個數據表並獲得所需的結果而不是將數據轉儲到csv? – vinodreddymk 2010-01-09 07:28:09

1

看起來你想計算兩個DataSet的symmetric difference。我們可以使用一些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; 
}