Question

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

quelqu'un peut m'aider?

Était-ce utile?

La solution

Si vous souhaitez que cette fonctionnalité examine un article de ScottGu dans Bibliothèque dynamique Linq . Je crois que ça fera ce que tu veux.

Bien que Lambda respecte le type, il est parfois utile de générer la requête à la volée, par opposition aux combinaisons possibles qu'un utilisateur peut trier, par exemple.

Modifier

J'ai corrigé votre méthode. Fondamentalement, vous devez créer une expression pour chaque accès membre.

 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;
        }
    }

Autres conseils

Vous voudrez peut-être envisager une autre méthode utilisant un objet Comparer personnalisé pour effectuer la comparaison. Vous pouvez ensuite écrire une comparaison personnalisée pour une personne qui les compare en fonction de leurs adresses électroniques.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top