题
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,根据其电子邮件地址对其进行比较。
不隶属于 StackOverflow