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

有人可以帮帮我吗?

有帮助吗?

解决方案

如果您希望此功能,请参阅ScottGu关于动态Linq库。我相信它会做你想要的。

虽然Lambda是类型安全的,但有时您可能希望动态生成查询,而不是拥有用户可以排序的所有可能组合。

修改

我修复了你的方法。基本上,您需要为每个成员访问创建一个表达式。

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

其他提示

您可能想要考虑采用自定义Comparer对象进行比较的另一种方法。然后,您可以为Person编写自定义Comparer,根据其电子邮件地址对其进行比较。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top