Метод расширения для сортировки списка в родительском объекте - PullRequest
1 голос
/ 29 апреля 2009
public class Person
{
    public string name { get; set; }
    public Email email { get; set; }

}

public class Email
{
    public string desc { get; set; }
}

public static IEnumerable<T> Sort<T>(this IEnumerable<T> source, string sortExpression, bool desc)
{            
    var param = Expression.Parameter(typeof(T), string.Empty);
    try
    {
        var property   = Expression.Property(param, sortExpression);
        var sortLambda = Expression.Lambda<Func<T, object>>(Expression.Convert(property, typeof(object)), param);

        if (desc)
        {
            return source.AsQueryable<T>().OrderByDescending<T, object>(sortLambda);
        }

        return source.AsQueryable<T>().OrderBy<T, object>(sortLambda);
    }
    catch (ArgumentException)
    {
        return source;
    }
}

        List<Person> vet = new List<Person>();

        Person p = new Person { name = "aaa", email = new Email { desc = "bbb@aaa.com" } };
        Person pp = new Person { name = "bbb", email = new Email { desc = "aaa@aaa.com" } };
        vet.Add(p);
        vet.Add(pp);

        vet.Sort("name",true); //works
        vet.Sort("email.desc",true) // doesnt work

кто-нибудь может мне помочь?

Ответы [ 2 ]

2 голосов
/ 29 апреля 2009

Возможно, вы захотите подумать о другом методе, который использует пользовательский объект Comparer для сравнения. Затем вы можете написать собственный Comparer for Person, который сравнивает их по их адресам электронной почты.

1 голос
/ 29 апреля 2009

Если вы хотите эту функциональность, загляните в статью ScottGu о Dynamic Linq Library . Я верю, что это будет делать то, что вы хотите.

Хотя лямбда-типы безопасны по типу, бывают ситуации, когда вам может потребоваться сгенерировать запрос на лету, а не иметь все возможные комбинации, которые пользователь может отсортировать, например.

Редактировать

Я исправил твой метод. По сути, вам нужно создать выражение для каждого члена доступа.

 public static IEnumerable<T> Sort<T>(this IEnumerable<T> source, string sortExpression, bool desc)
    {
        var param = Expression.Parameter(typeof(T), string.Empty);
        try
        {
            var fields = sortExpression.Split('.');
            Expression property = null;
            Expression parentParam = param;
            foreach (var field in fields)
            {
                property = Expression.Property(parentParam, field);
                parentParam = property;

            }

            var sortLambda = 
                Expression.Lambda<Func<T, object>>(
                  Expression.Convert(property, typeof(object)), param);

            if (desc)
            {
                return source.AsQueryable<T>().
                     OrderByDescending<T, object>(sortLambda);
            }

            return source.AsQueryable<T>().
                 OrderBy<T, object>(sortLambda);
        }
        catch (ArgumentException)
        {
            throw;
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...