2013-02-21 28 views
20

Tôi có hai datatables và tôi muốn có được sự khác biệt giữa chúng. Dưới đây là một ví dụ:Làm thế nào để có được sự khác biệt giữa hai DataTables

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

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

Tôi chỉ muốn kết quả dưới dạng dữ liệu mà là ở table1 và không có trong table2 (table1-table2)

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

Tôi cố gắng để sử dụng hai giải pháp tương tự qua LINQ, nhưng nó luôn trả về table1 và không phải table1-table2. Đây là giải pháp đầu tiên:

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

giải pháp thứ hai:

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

Vì vậy, đâu là sai lầm? Cảm ơn bạn rất nhiều cho tất cả các câu trả lời của bạn. :)

+2

Trừ séc kiểm tra hoặc không cùng một trường hợp. Không phải thời tiết thuộc tính tương ứng của chúng là giống hệt nhau. Bạn có thể sử dụng quá tải chấp nhận EqualityComparer hoặc bạn có thể điều tra phương thức mở rộng exceptBy() được triển khai trong nhiều thư viện LINQ + khác nhau, cũng trong Jon Skeets MoreLinq (http://code.google.com/p/morelinq/) – Tormod

+2

@ Tormod, nhưng sau đó sử dụng 'DataRowComparer' trong giải pháp đầu tiên của anh ta là gì? Nó ghi đè 'public bool Equals (Trow leftRow, TRow rightRow)' để so sánh các giá trị cột thực tế. – hometoast

+2

Bạn có thể chỉ ra cách bạn đang truy xuất các datatables của bạn? Có thể dữ liệu khác với bạn mong đợi không? Tôi đã làm một mẫu nhanh chóng trong LINQPad và giải pháp đầu tiên của bạn dường như làm việc tốt. – goric

Trả lời

7

Bạn có thể thử đoạn mã sau ...

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

Tôi sẽ cố gắng để làm điều đó về mặt kĩ cột chứ không phải là một DataTable.

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

Chỉ cần thêm một .Select() vào câu trả lời của bạn ...

0

Hãy thử phương pháp dưới đây:

khởi:

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"); 

Giải pháp:

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(); 

Trên soluti cũng hoạt động khi có các hàng mới trong bảng 2 không có trong bảng 1.

distintTable constains CD.

0

Hãy thử dưới đây, điều này khá cơ bản. Hợp nhất hai bộ lại với nhau và nhận được sự khác biệt. Nếu các bộ không sắp xếp đúng cách, thì điều này sẽ không hoạt động.

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

Tôi vừa trải qua điều này và muốn chia sẻ những phát hiện của mình. Đối với ứng dụng của tôi nó là một cơ chế đồng bộ dữ liệu, nhưng tôi nghĩ bạn sẽ thấy cách áp dụng cho câu hỏi gốc.

Trong trường hợp của tôi, tôi đã có một DataTable đại diện cho dữ liệu tải lên cuối cùng của tôi và đôi khi trong tương lai, tôi cần để có được tình trạng hiện tại của dữ liệu và chỉ tải lên sự khác biệt.

// 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); 

Tôi hy vọng điều này sẽ hữu ích.Tôi đã chiến đấu với điều này trong một vài giờ, và phát hiện rất nhiều sai dẫn trên interwebz, và kết thúc so sánh RowStates sau khi sáp nhập một vài cách khác nhau

+0

Khi tôi thử tất cả những gì tôi nhận được từ GetChanges là sự kết hợp của các bộ, không phải là sự khác biệt. –

1

Hãy thử điều này

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

Hãy thử dưới đây, điều này là khá căn bản. Hợp nhất hai bộ lại với nhau và nhận được sự khác biệt. Nếu các bộ không sắp xếp đúng cách, thì điều này sẽ không hoạt động. Đang cố gắng kiểm tra cùng một số

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(); 
Các vấn đề liên quan