2013-02-21 22 views
20

Bu iki veritabam var ve aralarındaki farkı almak istiyorum. Bir örnek:İki DataTables arasında fark nasıl bulunur?

Table1 
------------------------- 
ID | Name 
-------------------------- 
1 | A 
2 | B 
3 | C 
-------------------------- 

Table2 
------------------------- 
ID | Name 
-------------------------- 
1 | A 
2 | B 
-------------------------- 

Sadece Tablo 1'de olup tablo2 içinde (Tablo 1-Tablo 2) veri olarak sonuç isteyen

ResultTable 
------------------------- 
ID | Name 
-------------------------- 
3 | C 
-------------------------- 

Linq ile bu iki benzer çözümler kullanmaya çalıştı, ama her zaman tablo1-tablo2 değil tablo1 döndürür.

DataTable table1= ds.Tables["table1"]; 
DataTable table2= ds.Tables["table2"]; 
var diff= table1.AsEnumerable().Except(table2.AsEnumerable(),DataRowComparer.Default); 

İkinci çözüm:

var dtOne = table1.AsEnumerable(); 
var dtTwo = table2.AsEnumerable(); 
var difference = dtOne.Except(dtTwo); 

Yani, hatadır İşte ilk çözüm mü? Bütün cevaplarınız için çok teşekkür ederim. :)

+2

Aynı sınama olup olmadığına bakıp gitmediğini kontrol etmek. İlgili özelliklerin aynı olup olmadığı değil. Bir EqualityComparer'ı kabul eden aşırı yüklemeyi kullanabilir veya çeşitli LINQ + kitaplıklarında uygulanan ExceptBy() uzantı yöntemini, ayrıca Jon Skeets MoreLinq'de (http://code.google.com/p/morelinq/) – Tormod

+2

@ Tormod, ama sonra ilk çözümde 'DataRowComparer' kullanımı nedir? Gerçek sütun değerlerini karşılaştırmak için 'public bool Equals (TRow leftRow, TRow rightRow) 'seçeneğini geçersiz kılar. – hometoast

+2

Veri dosyalarınızı nasıl aldığınızı gösterir misiniz? Verilerin beklediğinizden farklı olması mümkün mü? LINQPad'de hızlı bir örnek yaptım ve ilk çözümün iyi çalışıyor gibi görünüyor. – goric

cevap

7

Aşağıdaki kodu deneyebilirsiniz ...

table1.AsEnumerable().Where(
    r =>!table2.AsEnumerable().Select(x=>x["ID"]).ToList().Contains(r["ID"])).ToList(); 
1

Bir sütun düzeyinde yerine bir DataTable bunu yapmak için çalışacağız.

IEnumerable<int> id_table1 = table1.AsEnumerable().Select(val=> (int)val["ID"]); 
IEnumerable<int> id_table2 = table2.AsEnumerable().Select(val=> (int)val["ID"]); 
IEnumerable<int> id_notinTable1= id_table2.Except(id_table1); 

Sadece

0

aşağıda yaklaşım deneyin ... Sorununuza bir .Select() ekleyerek:

Başlatma:

var columnId = new DataColumn("ID", typeof (int)); 
var columnName = new DataColumn("Name", typeof (string)); 
var table1 = new DataTable(); 
table1.Columns.AddRange(new[] {columnId, columnName}); 
table1.PrimaryKey = new[] {columnId}; 
table1.Rows.Add(1, "A"); 
table1.Rows.Add(2, "B"); 
table1.Rows.Add(3, "C"); 

var table2 = table1.Clone(); 
table2.Rows.Add(1, "A"); 
table2.Rows.Add(2, "B"); 
table2.Rows.Add(4, "D"); 

Çözüm: soluti Üstü

var table3 = table1.Copy(); 
table3.AcceptChanges(); 
table3.Merge(table2); 

var distinctRows = from row in table3.AsEnumerable() 
        where row.RowState != DataRowState.Modified 
        select row; 

var distintTable = distinctRows.CopyToDataTable(); 

Ayrıca, tablo2'de bulunmayan yeni satırlar olduğunda tablo1'de çalışır.

distintTable constains ve D.

0

Aşağıdan deneyin, bu oldukça basit. Birlikte iki seti birleştirin ve farkı alın. Setler düzgün bir şekilde hizalanmazsa, bu çalışmaz.

DataSet firstDsData = new DataSet(); 
DataSet secondDsData = new DataSet(); 
DataSet finalDsData = new DataSet(); 
DataSet DifferenceDataSet = new DataSet(); 
finalDsData.Merge(firstDsData); 
finalDsData.AcceptChanges(); 
finalDsData.Merge(secondDsData); 
DifferenceDataSet = finalDsData.GetChanges(); 
5

Sadece bunu gözden geçirdim ve bulgularımı paylaşmak istedim. Uygulamam için bir veri senkronizasyon mekanizmasıdır, ancak bunun orijinal soru için nasıl geçerli olduğunu göreceksiniz. Benim durumumda

, benim son veri yükleme temsil ve ileride ben veri akım devlet olsun ve sadece farklılıkları upload gereken bir DataTable vardı.

// get the Current state of the data 
DataTable dtCurrent = GetCurrentData(); 

// get the Last uploaded data 
DataTable dtLast = GetLastUploadData(); 
dtLast.AcceptChanges(); 

// the table meant to hold only the differences 
DataTable dtChanges = null; 

// merge the Current DataTable into the Last DataTable, 
// with preserve changes set to TRUE 
dtLast.Merge(dtCurrent, true); 

// invoke GetChanges() with DataRowState.Unchanged 
// !! this is the key !! 
// the rows with RowState == DataRowState.Unchanged 
// are the differences between the 2 tables 
dtChanges = dtLast.GetChanges(DataRowState.Unchanged); 

Umarım bu yardımcı olur.Birkaç saat bu mücadele ettiler ve Interwebz üzerinde yanlış potansiyel müşteri bir sürü bulundu ve aşağıda deneyin bu

DataTable dtmismatch = Table1.AsEnumerable().Except(Table2.AsEnumerable(), DataRowComparer.Default).CopyToDataTable<DataRow>(); 
+0

Tüm bunları denediğimde GetChanges'ten çıkıp tüm setlerin birliği, fark değil. –

1

birleştirdikten sonra RowStates karşılaştıran sona erdi, bu güzel temel. Birlikte iki seti birleştirin ve farkı alın. Setler düzgün bir şekilde hizalanmazsa, bu çalışmaz. Aynı

DataSet firstDsData = new DataSet(); 
DataSet secondDsData = new DataSet(); 
DataSet finalDsData = new DataSet(); 
DataSet DifferenceDataSet = new DataSet(); 
finalDsData.Merge(firstDsData); 
finalDsData.AcceptChanges(); 
finalDsData.Merge(secondDsData); 
DifferenceDataSet = finalDsData.GetChanges(); 
İlgili konular