Skip to content

Instantly share code, notes, and snippets.

@joshgo
Last active December 15, 2015 17:09
Show Gist options
  • Save joshgo/5294095 to your computer and use it in GitHub Desktop.
Save joshgo/5294095 to your computer and use it in GitHub Desktop.
DataRow Comparer == Solution for sorting rows with your own comparer. Helps with customizing the comparison function. Helps the C# Sort() match the ORDER BY in SQL. http://msmvps.com/blogs/deborahk/archive/2009/07/23/linq-sorting-a-datatable.aspx http://stackoverflow.com/questions/3808158/string-comparison-differences-between-net-and-t-sql
public class RowComparer : IComparer<System.Data.DataRow>
{
public Dictionary<int, bool> SortColumns { get; set; }
public int Compare(System.Data.DataRow x, System.Data.DataRow y)
{
foreach (int key in SortColumns.Keys)
{
int compareResult;
if (x.ItemArray[key] == DBNull.Value && y.ItemArray[key] == DBNull.Value)
compareResult = 0;
else if (x.ItemArray[key] == DBNull.Value)
compareResult = -1;
else if (y.ItemArray[key] == DBNull.Value)
compareResult = 1;
else if (x.Table.Columns[key].DataType.Name == typeof(Decimal).Name)
compareResult = DefaultCompare<decimal>(x.ItemArray[key], y.ItemArray[key]);
else if (x.Table.Columns[key].DataType.Name == typeof(DateTime).Name)
compareResult = DefaultCompare<DateTime>(x.ItemArray[key], y.ItemArray[key]);
else if (x.Table.Columns[key].DataType.Name == typeof(string).Name)
compareResult = String.Compare(x.ItemArray[key].ToString(),
y.ItemArray[key].ToString(),
System.Globalization.CultureInfo.CurrentCulture,
System.Globalization.CompareOptions.OrdinalIgnoreCase);
else if (x.Table.Columns[key].DataType.Name == typeof(bool).Name)
compareResult = DefaultCompare<bool>(x.ItemArray[key], y.ItemArray[key]);
else
{
switch(x.Table.Columns[key].DataType.Name.ToUpper())
{
case "INT16":
compareResult = DefaultCompare<Int16>(x.ItemArray[key], y.ItemArray[key]);
break;
case "Int32":
compareResult = DefaultCompare<Int32>(x.ItemArray[key], y.ItemArray[key]);
break;
case "INT64":
compareResult = DefaultCompare<Int64>(x.ItemArray[key], y.ItemArray[key]);
break;
case "UINT16":
compareResult = DefaultCompare<UInt16>(x.ItemArray[key], y.ItemArray[key]);
break;
case "UINT32":
compareResult = DefaultCompare<UInt32>(x.ItemArray[key], y.ItemArray[key]);
break;
case "UINT64":
compareResult = DefaultCompare<UInt64>(x.ItemArray[key], y.ItemArray[key]);
break;
case "DOUBLE":
compareResult = DefaultCompare<double>(x.ItemArray[key], y.ItemArray[key]);
break;
default:
throw new ApplicationException(string.Format("Type [{0}] does not have a comparer.", x.Table.Columns[key].DataType.Name));
}
}
if (compareResult != 0)
return SortColumns[key] ? compareResult: -compareResult;
}
return 0;
}
private int DefaultCompare<T>(object a, object b)
{
return Comparer<T>.Default.Compare((T) a, (T) b);
}
}
@joshgo
Copy link
Author

joshgo commented Apr 3, 2013

TODO:

  • Convert to using Expressions/ExpressionTrees to speed up comparison

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment