Giải pháp của tôi:
public static Func<Student, object> BuildPredicate(string propertyName)
{
Type studentType = typeof(Student);
ParameterExpression studentParam = Expression.Parameter(studentType, "x");
MemberInfo ageProperty = studentType.GetProperty(propertyName);
MemberExpression valueInNameProperty = Expression.MakeMemberAccess(studentParam, ageProperty);
UnaryExpression expression = Expression.Convert(valueInNameProperty, typeof (object));
Expression<Func<Student, object>> orderByExpression = Expression.Lambda<Func<Student, object>>(expression, studentParam);
return orderByExpression.Compile();
}
trong làm cho mã biểu hiện của bạn được thêm đúc để object
.
Đó là cách bạn có thể tạo ra một chuỗi các ThenBy
:
var sortedStudents = students.OrderBy(BuildPredicate("Age"));
foreach (var property in typeof(Student).GetProperties().Where(x => !String.Equals(x.Name, "Age")))
{
sortedStudents = sortedStudents.ThenBy(BuildPredicate(property.Name));
}
var result = sortedStudents.ToList();
Cuối cùng, lớp Student
mẫu:
public class Student
{
public int Age { get; set; }
public string Name { get; set; }
}
Cập nhật:
cách tiếp cận khác là sử dụng các thuộc tính để đánh dấu các mục thích hợp từ số Student
của bạn để sử dụng chúng trong OrderBy
và ThenBy
. Giống như:
public class Student
{
[UseInOrderBy]
public int Age { get; set; }
[UseInOrderBy(Order = 1)]
public string Name { get; set; }
}
[AttributeUsage(AttributeTargets.Property)]
internal class UseInOrderByAttribute : Attribute
{
public int Order { get; set; }
}
Đó là cách bạn có thể xây dựng sắp xếp chuỗi sử dụng UseInOrderByAttribute
:
Type studentType = typeof (Student);
var properties = studentType.GetProperties()
.Select(x => new { Property = x, OrderAttribute = x.GetCustomAttribute<UseInOrderByAttribute>() })
.Where(x => x.OrderAttribute != null)
.OrderBy(x => x.OrderAttribute.Order);
var orderByProperty = properties.FirstOrDefault(x => x.OrderAttribute.Order == 0);
if (orderByProperty == null)
throw new Exception("");
var sortedStudents = students.OrderBy(BuildPredicate(orderByProperty.Property.Name));
foreach (var property in properties.Where(x => x.Property.Name != orderByProperty.Property.Name))
{
sortedStudents = sortedStudents.ThenBy(BuildPredicate(property.Property.Name));
}
var result = sortedStudents.ToList();
Fix: BuildPredicate
có thể bằng văn bản mà không cần dynamic
. BuildPredicate
mã mẫu được thay đổi.
Nguồn
2013-01-12 13:53:56
Để làm rõ - bạn đang tìm kiếm một cách để xây dựng một Biểu thức duy nhất, bạn có thể chuyển đến .OrderBy sẽ tái tạo chức năng truyền một chuỗi các Biểu thức tới .OrderBy và .ThenBy, co rrect? –
Dupe http://stackoverflow.com/questions/41244/dynamic-linq-orderby – aquinas