动态顺序通过使用 linq 动态



我正在尝试使用linq.dynamic将此Func转换为使用字符串值。

目前我有

Func<IQueryable<Customer>, IOrderedQueryable<Customer>> orderBy = o => o.OrderBy(c => c.Postcode);

但我想做

string sortItem = "customer";
string order = "ASC"
Func<IQueryable<Customer>, IOrderedQueryable<Customer>> orderBy = o => o.OrderBy(sortItem + " " + order);

我正在使用 Linq.Dynamic 库,但我无法让它与函数一起使用。

任何帮助...

就像另一个答案所暗示的那样,这可能是不可能的。 但是,我想发布一些我最近编写的代码来做类似的事情:

// single column sorting support
var sortColumnIndex = Convert.ToInt32(Request["iSortCol_0"]);
Func<LegalComplianceDatatable, string> orderingFunction = (c => sortColumnIndex == 0 ? c.HomeCountry :
                                                    sortColumnIndex == 1 ? c.HostCountry :
                                                    sortColumnIndex == 2 ? c.YearOneRate :
                                                    sortColumnIndex == 3 ? c.YearOtherRate :
                                                    sortColumnIndex == 4 ? c.RateType :
                                                    c.HostCountry);
if (Request["sSortDir_0"] == "desc")
{
    filteredResults = filteredResults.OrderByDescending(orderingFunction);
}
else
{
    filteredResults = filteredResults.OrderBy(orderingFunction);
}
我没有

使用过Linq.Dynamic,但是如果您愿意构建自己的表达式树,则可以实现此目的。例如:

public static class IQueryableExtension
{
    public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> query, string propertyName)
    {
        var memberProp = typeof(T).GetProperty(propertyName);
        var method = typeof(IQueryableExtension).GetMethod("OrderByInternal")
                                   .MakeGenericMethod(typeof(T), memberProp.PropertyType);
        return (IOrderedQueryable<T>)method.Invoke(null, new object[] { query, memberProp });
    }
    public static IOrderedQueryable<T> OrderByInternal<T, TProp>(IQueryable<T> query, PropertyInfo memberProperty)
    {
        if (memberProperty.PropertyType != typeof(TProp)) throw new Exception();
        var thisArg = Expression.Parameter(typeof(T));
        var lamba = Expression.Lambda<Func<T, TProp>>(Expression.Property(thisArg, memberProperty), thisArg);
        return query.OrderBy(lamba);
    }
}

你可以这样使用它:

IQueryable<Customer> query; // Some query
query = query.OrderBy("Name"); // Will return an IOrderedQueryable<Customer>

这是升序排序的逻辑,无需检查(您需要确保属性存在,依此类推),并且可以优化某些内容(例如反射的方法调用)。它应该让你开始。

最新更新