If i have two data tables with same structure,the same primary key and the same number of columns .
How to compare their content
and detect the cells which are not the same in the two data tables ?
ex:
TB_Offline
emp_num(key) salary ov
455 3000 67.891
677 5000 89.112
778 6000 12.672
TB_Online
emp_num(key) salary ov
455 3000 67.891
677 5000 50.113
778 5500 12.672
I want to get result like this(or some structure to show the differences) :
emp_num(key)| salary_off |salary_on|s1 | ov_off | ov_on |s2
677 | 5000 | 5000 | 1 | 89.112 | 50.113 | 0
778 | 6000 | 5500 | 0 | 12.672 | 12.672 | 1
NOTE:
455 doesn't exist in the result because it was the exact in all columns among the two datatables.
Here's an implementation in a fairly generic method that compares two DataTables and returns another DataTable with the differences shown.
Populating the DataTables...
/// Build data and test the underlying method. public void Main() { Dictionary columns = new Dictionary(); columns.Add("emp_num", typeof(int)); columns.Add("salary", typeof(int)); columns.Add("ov", typeof(double)); DataTable left = new DataTable(); foreach(KeyValuePair column in columns) { left.Columns.Add(column.Key, column.Value); } left.Rows.Add(455, 3000, 67.891); left.Rows.Add(677, 5000, 89.112); left.Rows.Add(778, 6000, 12.672); left.Rows.Add(9001, 5500, 12.672); left.Rows.Add(4, null, 9.2); //left.Dump("Left"); DataTable right = new DataTable(); right.Columns.Add("outlier", typeof(string)); foreach (KeyValuePair column in columns) { right.Columns.Add(column.Key, column.Value); } right.Columns.Add("float", typeof(float)); right.Rows.Add(0, 455, 3000, 67.891, 5); right.Rows.Add(1, 677, 5000, 50.113, 5); right.Rows.Add(2, 778, 5500, 12.672, 6); right.Rows.Add(2, 9000, 5500, 12.672, 6); right.Rows.Add(3, 4, 10, 9.2, 7); //right.Dump("Right"); // Compare. DataTable results = Compare(left, right, "emp_num"); //results.Dump("Results"); // Fancy table output via LINQPad. // Get the comparison columns for display. List comparedColumns = new List(); foreach (DataColumn column in results.Columns) { comparedColumns.Add(column.ColumnName); } // Display the comparison rows. Console.WriteLine(string.Join(", ", comparedColumns)); foreach(DataRow row in results.Rows) { Console.WriteLine(string.Join(", ", row.ItemArray)); } }
Generic Method: DataTable Compare(DataTable, DataTable)
/// Compares the values of each row in the provided DataTables and returns any rows that have a difference based on a provided 'key' column. /// the 'pre' data. /// the 'post' data. /// Name of the column to use for matching rows. /// New DataTable populated with difference rows only. public DataTable Compare(DataTable left, DataTable right, string keyColumn) { const string Pre = "_Pre"; const string Post = "_Post"; DataColumn leftKey = left.Columns.Contains(keyColumn) ? left.Columns[keyColumn] : null; DataColumn rightKey = right.Columns.Contains(keyColumn) ? right.Columns[keyColumn] : null; if (leftKey == null || rightKey == null) { return null; } // Get the matching columns between the two tables for doing comparisons. List comparisonColumns = new List(); DataTable results = new DataTable(); // Adding the key column to the front for sake of ease of viewing. results.Columns.Add(new DataColumn(leftKey.ColumnName, leftKey.DataType)); foreach (DataColumn column in left.Columns) { if(column == leftKey) { continue; } // Remove any columns that are not present in the compare table. foreach (DataColumn compareColumn in right.Columns) { if (column.ColumnName == compareColumn.ColumnName && column.DataType == compareColumn.DataType) { comparisonColumns.Add(column.ColumnName); results.Columns.Add(new DataColumn(column.ColumnName + Pre, column.DataType)); results.Columns.Add(new DataColumn(column.ColumnName + Post, column.DataType)); break; } } } foreach (DataRow leftRow in left.Rows) { object key = leftRow.Field(leftKey); string filterExpression = string.Format("{0} = {1}", keyColumn, key); DataRow rightRow = right.Select(filterExpression).SingleOrDefault(); // Need a row for a comparison to be valid. if (rightRow == null) { continue; } List comparison = new List(); comparison.Add(key); bool isDiff = false; foreach (string comparisonColumn in comparisonColumns) { object pre = leftRow.ItemArray[left.Columns.IndexOf(comparisonColumn)]; comparison.Add(pre); object post = rightRow.ItemArray[right.Columns.IndexOf(comparisonColumn)]; comparison.Add(post); // Only need the row if the values differ in at least one column. isDiff |= (pre == null && post != null) || (pre != null && post == null) || (!pre.Equals(post)); } if (isDiff) { results.Rows.Add(comparison.ToArray()); } } return results; }
Output:
emp_num, salary_Pre, salary_Post, ov_Pre, ov_Post 677, 5000, 5000, 89.112, 50.113 778, 6000, 5500, 12.672, 12.672 4, , 10, 9.2, 9.2
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With