Question
I built an application which displays the records from database in the window and checks the the database for new records every couple of seconds. The problem is that the window blinks each time I check for new records and I want to fix it. I have tried to compare the old datatable with the new one and refresh only if they are different. Does anyone know what is the best practice for such cases? I tried to do it the following way but it doesn't work:
private bool GetBelongingMessages()
{
bool result = false;
DataTable dtTemp = OleDbWorks.GetBelongingMessages(currentCallID);
if(dtTemp != dtMessages)
{
dtMessages = dtTemp;
result = true;
}
else
{
result = false;
}
return result;
}
Solution
First off, it's important to recognize that what you're comparing in your code is the references of the datatables, not the contents of the datatables. In order to determine if both datatables have the same contents, you're going to have to loop through all of the rows and columns and see if they're equal:
//This assumes the datatables have the same schema...
public bool DatatablesAreSame(DataTable t1, DataTable t2) {
if (t1.Rows.Count != t2.Rows.Count)
return false;
foreach (DataColumn dc in t1.Columns) {
for (int i = 0; i < t1.Rows.Count; i++) {
if (t1.Rows[i][dc.ColumnName] != t2.Rows[i][dc.ColumnName]) {
return false;
}
}
}
return true;
}
OTHER TIPS
I've been trying to find a way to do DataTable comparison for a while and ended up writing up my own function, here is what I got:
bool tablesAreIdentical = true;
// loop through first table
foreach (DataRow row in firstTable.Rows)
{
foundIdenticalRow = false;
// loop through tempTable to find an identical row
foreach (DataRow tempRow in tempTable.Rows)
{
allFieldsAreIdentical = true;
// compare fields, if any fields are different move on to next row in tempTable
for (int i = 0; i < row.ItemArray.Length && allFieldsAreIdentical; i++)
{
if (!row[i].Equals(tempRow[i]))
{
allFieldsAreIdentical = false;
}
}
// if an identical row is found, remove this row from tempTable
// (in case of duplicated row exist in firstTable, so tempTable needs
// to have the same number of duplicated rows to be considered equivalent)
// and move on to next row in firstTable
if (allFieldsAreIdentical)
{
tempTable.Rows.Remove(tempRow);
foundIdenticalRow = true;
break;
}
}
// if no identical row is found for current row in firstTable,
// the two tables are different
if (!foundIdenticalRow)
{
tablesAreIdentical = false;
break;
}
}
return tablesAreIdentical;
Compared to Dave Markle's solution, mine treats two table with same records but in different orders as identical. Hope this helps whoever stumbles upon this thread again.
You have to cast objects t1.Rows[i][dc.ColumnName] and t1.Rows[i][dc.ColumnName] otherwise the statement t1.Rows[i][dc.ColumnName] != t2.Rows[i][dc.ColumnName] is always true. I modified the code the following way:
for(int i = 0; i < t1.Rows.Count; i++)
{
if((string)t1.Rows[i][1] != (string)t2.Rows[i][1])
return false;
}
and it works but it's not an elegant solution.
public Boolean CompareDataTables(DataTable table1, DataTable table2)
{
bool flag = true;
DataRow[] row3 = table2.Select();
int i = 0;// row3.Length;
if (table1.Rows.Count == table2.Rows.Count)
{
foreach (DataRow row1 in table1.Rows)
{
if (!row1.ItemArray.SequenceEqual(row3[i].ItemArray))
{
flag = false;
break;
}
i++;
}
}
else
{
flag = false;
}
return flag;
}
// here this function will gave boolean as result return true if both are same else return false if both are not same