Как создать инструкцию OrderBy, используя отраженное значение? - PullRequest
1 голос
/ 16 января 2012

Я хотел бы создать метод, который упорядочивает список IEnumerable по заданному свойству, где свойство передается в метод с помощью строки, т.е.я пытаюсь эмулировать динамически).

string sortName = "SerialNumber";
IEnumerable<PartSummary> partList = FunctionToCreateList();
partOrderedList = partList.OrderBy(what do I stick in here);

, что эквивалентно

IEnumerable<PartSummary> partList = FunctionToCreateList();
partOrderedList = partList.OrderBy(p => p.SerialNumber);

Как мне это сделать?

Ответы [ 2 ]

1 голос
/ 16 января 2012

Вы говорите, что хотите передать заказ в ваш метод?Если это так, вы можете использовать это:

Expression<Func<PartSummary, bool>> orderByClause

Тогда вы можете сделать это:

partOrderedList = partList.OrderBy(orderByClause);

Затем вы можете обработать ваш заказ на бизнес-уровне или в любом другом месте.

Хорошо, обновите: если вы хотите передать имя столбца в виде строки, вы можете сделать что-то вроде следующего:

Создать статический класс для метода расширения (ссылка: http://social.msdn.microsoft.com/Forums/en-US/linqprojectgeneral/thread/39028ad2-452e-409f-bc9e-d1b263e921f6/):

static class LinqExtensions
{
    public static IQueryable<T> OrderBy<T>(this IQueryable<T> source, string sortingColumn, bool isAscending)
    {

        if (String.IsNullOrEmpty(sortingColumn))
        {
            return source;
        }

        ParameterExpression parameter = Expression.Parameter(source.ElementType, String.Empty);

        MemberExpression property = Expression.Property(parameter, sortingColumn);
        LambdaExpression lambda = Expression.Lambda(property, parameter);

        string methodName = isAscending ? "OrderBy" : "OrderByDescending";

        Expression methodCallExpression = Expression.Call(typeof(Queryable), methodName,
                                            new Type[] { source.ElementType, property.Type },
                                            source.Expression, Expression.Quote(lambda));

        return source.Provider.CreateQuery<T>(methodCallExpression);
    }
}

Затем вы можете создать свой метод:

   static IQueryable<PartSummary> FunctionToCreateList()
    {
        IList<PartSummary> list = new List<PartSummary>();
        list.Add(new PartSummary
                     {
                         Id = 1,
                         SerialNumber = "A",
                     });
        list.Add(new PartSummary
                     {
                         Id = 2,
                         SerialNumber = "B",
                     });
        return list.AsQueryable();
    }

И затем вызвать свой метод:

   static void Main(string[] args)
    {
        IQueryable<PartSummary> partOrderedList = FunctionToCreateList();
        PartSummary partSummary = new PartSummary();
        string sortBy = "Id";

        partOrderedList = partOrderedList.OrderBy(sortBy, false);

        foreach (PartSummary summary in partOrderedList)
        {
            Console.WriteLine(summary.Id + ", " + summary.SerialNumber);
        }
        Console.ReadLine();

    }

Теперь вы можете передать имя столбца в виде строки иsort.

Надеюсь, это поможет!

0 голосов
/ 16 января 2012

Вы также можете избежать расширения и просто использовать скомпилированное дерево выражений для этого:

    public Func<T, object> ResolveToProperty<T>(String propertyName)
    {
        Type t = typeof(T);
        var paramExpression = Expression.Parameter(t, "element");
        var propertyExpression = Expression.Property(paramExpression, propertyName);
        return Expression.Lambda<Func<T, object>>(propertyExpression, paramExpression).Compile();
    }

    string sortName = "SerialNumber";
    IEnumerable<PartSummary> partList = FunctionToCreateList();
    var partOrderedList = partList.OrderBy(ResolveToProperty<PartSummary>(sortName));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...