2012-03-09 24 views
6

Bu konuda yanlış olanları lütfen kontrol edebilir misiniz?DataTable Birliği

bu birliği gerekir ama ("Emir" iki kez oluşur çünkü) Buraya

DataTable dt1 = new DataTable(); 
dt1.Columns.Add(new DataColumn("Name")); 
dt1.Rows.Add(dt1.NewRow()["Name"] = "Imran"); 
dt1.Rows.Add(dt1.NewRow()["Name"] = "Amir"); 
dt1.Rows.Add(dt1.NewRow()["Name"] = "Asif"); 

DataTable dt2 = new DataTable(); 
dt2.Columns.Add(new DataColumn("Name")); 
dt2.Rows.Add(dt2.NewRow()["Name"] = "Tandulkar"); 
dt2.Rows.Add(dt2.NewRow()["Name"] = "Amir"); 
dt2.Rows.Add(dt2.NewRow()["Name"] = "Sheqwag"); 

DataTable dtUnion = dt1.AsEnumerable() 
    .Union(dt2.AsEnumerable()).CopyToDataTable<DataRow>(); 

cevap

9

sorunu 6 rekoru 5 yerine döndüren Linq Eğer Name karşılaştırmak istiyorum bilmiyor olmasıdır. Bunun yerine, tüm nesne türleri için yaptığı, iki farklı örnek için farklı olan karma karşılaştırır.

Yapmanız gereken şey, Union yöntemine iki öğenin nasıl karşılaştırılacağını anlatmaktır. İki veri satırını istediğiniz gibi karşılaştıran özel bir IEqualityComparer oluşturarak bunu yapabilirsiniz. İşte

örnek bir uygulamasıdır:

class CustomComparer : IEqualityComparer<DataRow> 
{ 
    #region IEqualityComparer<DataRow> Members 

    public bool Equals(DataRow x, DataRow y) 
    { 
     return ((string)x["Name"]).Equals((string)y["Name"]); 
    } 

    public int GetHashCode(DataRow obj) 
    { 
     return ((string)obj["Name"]).GetHashCode(); 
    } 

    #endregion 
} 

sonra bu karşılaştırıcısı örneğine geçmek gerekir Union arayarak:
http://msdn.microsoft.com/en-us/library/bb358407.aspx

: Daha fazla bilgi için buraya bakınız

var comparer = new CustomComparer(); 
DataTable dtUnion = dt1.AsEnumerable() 
     .Union(dt2.AsEnumerable(), comparer).CopyToDataTable<DataRow>(); 

Tavsiye edilen kelime:
Linq, DataRow'un olmadığı özelleştirilmiş veri sınıflarıyla en iyisidir. Sınıfta gerçek bir Name özelliğine sahip olmak en iyisidir, sadece Linq gerçekten parlayabilir.
Dinamik şemanın esnekliğine ihtiyacınız yoksa, DataTable'dan uzak kalmalı ve tam olarak ihtiyacınız olana benzeyen özel sınıflar kullanmalısınız, çünkü DataTable son derece şişirilmiş ve yavaştır. senin datatables' şemalar aynıdır

3

varsa, sadece bu yüzden gibi mevcut DataRowComparer.Default kullanabilirsiniz:

DataTable dtUnion = dt1.AsEnumerable().Union(dt2.AsEnumerable()).Distinct(DataRowComparer.Default).CopyToDataTable<DataRow>(); 

Ve daha o 2 tablo birlik gerektiğinde Toplama işlevi çok kullanışlı olduğunu, örneğin:

// Create a table "template" 
DataTable dt = new DataTable(); 
dt.Columns.Add(new DataColumn("Name")); 

// Create a List of DataTables and add 3 identical tables 
List<DataTable> dtList = new List<DataTable>(); 
dtList.AddRange(new List<DataTable>() { dt.Clone(), dt.Clone(), dt.Clone()}); 

// Populate the 3 clones with some data 
dtList[0].Rows.Add("Imran"); 
dtList[0].Rows.Add("Amir"); 
dtList[0].Rows.Add("Asif"); 

dtList[1].Rows.Add("Tandulkar"); 
dtList[1].Rows.Add("Amir"); 
dtList[1].Rows.Add("Sheqwag"); 

dtList[2].Rows.Add("John"); 
dtList[2].Rows.Add("Sheqwag"); 
dtList[2].Rows.Add("Mike"); 

// Union the 3 clones into a single DataTable containing only distinct rows 
DataTable dtUnion = dtList 
        .Select(d => d.Select().AsEnumerable()) 
        .Aggregate((current, next) => current.Union(next)) 
        .Distinct(DataRowComparer.Default) 
        .CopyToDataTable<DataRow>();