我在VS2008动态LINQ示例中找到了一个示例,允许您使用类似sql的字符串(例如OrderBy(“Name, Age DESC”))进行排序。不幸的是,所包含的方法只适用于IQueryable<T>。有什么办法得到这个功能IEnumerable<T>?


当前回答

将List转换为IEnumerable或Iquerable,使用System.LINQ.Dynamic命名空间添加,然后你可以用逗号分隔的字符串提到OrderBy方法,OrderBy方法默认来自System.LINQ.Dynamic。

其他回答

我想使用反射来获得你想要排序的任何属性是可行的:

IEnumerable<T> myEnumerables
var query=from enumerable in myenumerables
          where some criteria
          orderby GetPropertyValue(enumerable,"SomeProperty")
          select enumerable

private static object GetPropertyValue(object obj, string property)
{
    System.Reflection.PropertyInfo propertyInfo=obj.GetType().GetProperty(property);
    return propertyInfo.GetValue(obj, null);
}

注意,使用反射比直接访问属性要慢得多,因此必须研究性能。

你可以将IEnumerable转换为IQueryable。

items = items.AsQueryable().OrderBy("Name ASC");

如果您正在使用规范(例如Ardalis规范)

using Microsoft.EntityFrameworkCore;

namespace TestExtensions;

public static class IQueryableExtensions
{
    public static void ApplyOrder<T>(ISpecificationBuilder<T> query, string propertyName, bool ascendingOrder)
    {
        if (ascendingOrder)
            query.OrderBy(T => EF.Property<object>(T!, propertyName));
        else
            query.OrderByDescending(T => EF.Property<object>(T!, propertyName));
    }
}

你可以这样做,对多个顺序

IOrderedEnumerable<JToken> sort;

if (query.OrderBys[0].IsDESC)
{
    sort = jarry.OrderByDescending(r => (string)r[query.OrderBys[0].Key]);
}
else
{
    sort = jarry.OrderBy(r =>
        (string) r[query.OrderBys[0].Key]); 
}

foreach (var item in query.OrderBys.Skip(1))
{
    if (item.IsDESC)
    {
        sort = sort.ThenByDescending(r => (string)r[item.Key]);
    }
    else
    {
        sort = sort.ThenBy(r => (string)r[item.Key]);
    }
}

我可以用下面的代码做到这一点。不需要编写长而复杂的代码。

 protected void sort_array(string field_name, string asc_desc)
        {

            objArrayList= Sort(objArrayList, field_name, asc_desc);
        }

        protected List<ArrayType> Sort(List<ArrayType> input, string property, string asc_desc)
        {
            if (asc_desc == "ASC")
            {

                return input.OrderBy(p => p.GetType()
                                           .GetProperty(property)
                                           .GetValue(p, null)).ToList();
            }
            else
            {
                return input.OrderByDescending(p => p.GetType()
                                               .GetProperty(property)
                                               .GetValue(p, null)).ToList();
            }
        }