开发者

Creating a sort function for a generic list

开发者 https://www.devze.com 2022-12-27 05:08 出处:网络
I have a method for sorting generic lists by the object fields: public static IQueryable<T> SortTable<T>(IQueryable<T> q, string sortfield, bool ascending)

I have a method for sorting generic lists by the object fields:

public static IQueryable<T> SortTable<T>(IQueryable<T> q, string sortfield, bool ascending)
{
    var p = Expression.Parameter(typeof(T), "p");

    if (typeof(T).GetProperty(sortfield).PropertyType == typeof(int?))
    {
        var x = Expression.Lambda<Func<T, int?>>(Expression.Property(p, sortfield), p);
        if (ascending)
            q = q.OrderBy(x);
        else
            q = q.OrderByDescending(x);
    }
    else if (typeof(T).GetProperty(sortfield).PropertyType == typeof(int))
    {
        var x = Expression.Lambda<Func<T, int>>(Expression.Property(p, sortfield), p);
 开发者_开发知识库       if (ascending)
            q = q.OrderBy(x);
        else
            q = q.OrderByDescending(x);
    }
    else if (typeof(T).GetProperty(sortfield).PropertyType == typeof(DateTime))
    {
        var x = Expression.Lambda<Func<T, DateTime>>(Expression.Property(p, sortfield), p);
        if (ascending)
            q = q.OrderBy(x);
        else
            q = q.OrderByDescending(x);
    }
    // many more for every type
    return q;
}

Is there any way I can collapse those ifs to a single generic statement? The main problem is that for the part Expression.Lambda<Func<T, int>> I am not sure how to write it generically.


If you expand Queryable.OrderBy to its definition then you don't have to use the generic overload of Expression.Lambda:

public static IQueryable<T> SortTable<T>(
    IQueryable<T> q, string sortfield, bool ascending)
{
    var p = Expression.Parameter(typeof(T), "p");
    var x = Expression.Lambda(Expression.Property(p, sortfield), p);

    return q.Provider.CreateQuery<T>(
               Expression.Call(typeof(Queryable),
                               ascending ? "OrderBy" : "OrderByDescending",
                               new Type[] { q.ElementType, x.Body.Type },
                               q.Expression,
                               x));
}


Won't this work?

    public static IQueryable<T> SortTable<T>(IQueryable<T> q, string sortfield, bool ascending)
    {
        var type = typeof(T).GetProperty(sortfield).PropertyType;
        var p = Expression.Parameter(typeof(T), "p");
        var x = Expression.Lambda<Func<T, type> >(Expression.Property(p, sortfield), p);
        if (ascending)
            q = q.OrderBy(x);
        else
            q = q.OrderByDescending(x);
        return q;
    }
0

精彩评论

暂无评论...
验证码 换一张
取 消