Sorting Generic Lists and IQueryable's With A Dynamic Property Name

by Bar Zohan 5. April 2010 21:12

For sorting IQueryable's

public enum SortDirection { Ascending, Descending }

public static IQueryable<T> DynamicSort<T>(this IQueryable<T> data , string columnName, SortDirection direction)
        {
            ParameterExpression param = Expression.Parameter(typeof(T), "item");
            string dir = direction == SortDirection.Ascending ? "OrderBy" : "OrderByDescending";
            PropertyInfo pi = typeof(T).GetProperty(columnName);

            Expression expr = Expression.Call(typeof(Queryable), dir, new Type[] { typeof(T), pi.PropertyType }, data.Expression, Expression.Lambda(Expression.Property(param, columnName), param));
            IQueryable<T> query = data.AsQueryable().Provider.CreateQuery<T>(expr);
            return query;
        }

Usage:

                SortDirection SortDirection = SortDirection.Ascending;

                var result = (from d in datamodel.Orders select new { Id = d.Id, Name= d.Name,Address = d.Street + " " + d.AddressTitle });

                if (SortExpression != "")
                {
                    result = result.DynamicSort("Name", SortDirection);
                }


For Sorting Generic Lists

 public enum SortDirection { Ascending, Descending }
    public class ListSorter<T> where T : class
    {
        public static List<T> Sort(List<T> listToSort, string propertyName, SortDirection direction, Type objectType)
        {
            Type propertyType = objectType;
            Type comparableInterface = propertyType.GetInterface("IComparable");
            if (comparableInterface == null)
                throw new Exception("Properties to sort by must be IComparable");
            listToSort.Sort(delegate(T x, T y)
            {
                PropertyInfo p1 = x.GetType().GetProperty(propertyName);
                PropertyInfo p2 = y.GetType().GetProperty(propertyName);
                object p1objvalue = p1.GetValue(x, null);
                object p2objvalue = p2.GetValue(y, null);
                object p1value = (Convert.ChangeType(p1objvalue, propertyType));
                object p2value = (Convert.ChangeType(p2objvalue, propertyType));
                if (direction == SortDirection.Ascending)
                    return ((IComparable)p1value).CompareTo(p2value);
                else
                    return ((IComparable)p2value).CompareTo(p1value);
            }
            ); return listToSort;

        }



        public static List<T> Sort(List<T> listToSort, string propertyName, SortDirection direction)
        {
            object tester = null;
            object testerValue = null;
            int i = 0;

            while (i < listToSort.Count && Convert.ToString(tester) == "")
            {
                PropertyInfo testerPropertyInfo = listToSort[i].GetType().GetProperty(propertyName);

                testerValue = testerPropertyInfo.GetValue(listToSort[i], null).ToString();

                tester = testerValue;

                i++;
            }


            try
            {
                tester = Convert.ToDouble(testerValue);
            }
            catch (Exception)
            {
                try
                {
                    tester = Convert.ToString(listToSort[0]);
                }
                catch (Exception)
                {
                }
            }


            listToSort.Sort(delegate(T x, T y)
            {
                PropertyInfo p1 = x.GetType().GetProperty(propertyName);
                PropertyInfo p2 = y.GetType().GetProperty(propertyName);
                object p1objvalue = p1.GetValue(x, null).ToString().Replace('.', ',');
                object p2objvalue = p2.GetValue(y, null).ToString().Replace('.', ',');
                object p1value = p1objvalue, p2value = p2objvalue;

                if ((tester is int || tester is double))
                {
                    if ((p1objvalue is string) && (Convert.ToString(p1objvalue) == ""))
                    {
                        p1objvalue = 0;
                    }

                    if ((p2objvalue is string) && (Convert.ToString(p2objvalue) == ""))
                    {
                        p2objvalue = 0;
                    }
                }
                p1value = Convert.ChangeType(p1objvalue, tester.GetType());

                p2value = Convert.ChangeType(p2objvalue, tester.GetType());

                if (direction == SortDirection.Ascending)
                    return ((IComparable)p1value).CompareTo(p2value);
                else
                    return ((IComparable)p2value).CompareTo(p1value);
            }
            ); return listToSort;

        }

    }

Usage:

 class Order
    {
        public int Id { get; set; }
        public string Product { get; set; }
        public int Count { get; set; }
    }

 

            List<Order> orders = new List<Order>();
            orders.Add(new Order(){Id = 1, Product = "a",Count = 3});
            orders.Add(new Order(){Id = 2,Product = "b", Count = 4});
            orders.Add(new Order() { Id = 3, Product = "c", Count = 1 });
            List<Order> sortedOrders = ListSorter<Order>.Sort(orders, "Count", SortDirection.Descending);

Powered by BlogEngine.NET 1.5.0.7
Theme by Mads Kristensen