I faced a situation where it was not possible to data in sql queries using any of the standard ways (Linq to SQL, Entity Framework, Stored Procedures, etc.) thus the data had to be sorted at controller method.
Little uncomfortable using static property names and wanted to pass the property name of the sort column as a string value, I ended up writing a custom comparer class as below
/// <summary>
/// Compares two objects of same type based on value of the SortBy property
/// </summary>
/// <typeparam name="T"></typeparam>
public class SortComparer<T> : Comparer<T>
{
public string SortBy = string.Empty;
public bool SortDescending = true;
public SortComparer() { }
public SortComparer(string sortBy, bool sortDescending)
{
SortBy = sortBy;
SortDescending = sortDescending;
}
public override int Compare(T x, T y)
{
PropertyInfo propInfo = x.GetType().GetProperty(SortBy);
if (propInfo != null)
{
var obj1 = propInfo.GetValue(x, new object[0]) as IComparable;
var obj2 = propInfo.GetValue(y, new object[0]) as IComparable;
if (obj1 != null)
{
if (obj2 != null)
{
return SortDescending ? obj2.CompareTo(obj1) : obj1.CompareTo(obj2);
}
else
{
return SortDescending ? -1 : 1;
}
}
else if (obj2 != null)
{
return SortDescending ? 1 : -1;
}
}
return 0;
}
}
Little uncomfortable using static property names and wanted to pass the property name of the sort column as a string value, I ended up writing a custom comparer class as below
/// <summary>
/// Compares two objects of same type based on value of the SortBy property
/// </summary>
/// <typeparam name="T"></typeparam>
public class SortComparer<T> : Comparer<T>
{
public string SortBy = string.Empty;
public bool SortDescending = true;
public SortComparer() { }
public SortComparer(string sortBy, bool sortDescending)
{
SortBy = sortBy;
SortDescending = sortDescending;
}
public override int Compare(T x, T y)
{
PropertyInfo propInfo = x.GetType().GetProperty(SortBy);
if (propInfo != null)
{
var obj1 = propInfo.GetValue(x, new object[0]) as IComparable;
var obj2 = propInfo.GetValue(y, new object[0]) as IComparable;
if (obj1 != null)
{
if (obj2 != null)
{
return SortDescending ? obj2.CompareTo(obj1) : obj1.CompareTo(obj2);
}
else
{
return SortDescending ? -1 : 1;
}
}
else if (obj2 != null)
{
return SortDescending ? 1 : -1;
}
}
return 0;
}
}