我有一个具有以下结构的课程
public class DisplayItem
{
public string Id { get; set; }
public SortFields SortFields { get; set; }
}
带有子类
public class SortFields
{
public string ProductNumber { get; set; }
public DateTime DateOfUpload { get; set; }
}
因此,我们的想法是根据SortFields类属性中的值对List进行排序。
我能想到的最基本的解决方案就是做这样的事情
public IEnumerable<DisplayItem> Sort(IEnumerable<DisplayItem> source, string sortBy, SortDirection sortDirection)
{
switch (sortBy)
{
case "Product Number":
switch (sortDirection)
{
case SortDirection.Ascending:
return source.OrderBy(x => x.SortFields.ProductNumber);
case SortDirection.Descending:
return source.OrderByDescending(x => x.SortFields.ProductNumber);
}
case "Uploaded Date":
{
//--do--
}
}
}
理想情况下,我希望能够在sortby方法中将sortBy作为参数传递,虽然我确实在互联网上找到了几个解决方案,但它们似乎无法对基类列表进行排序子类属性。
有没有办法可以将子类属性作为参数传递,并且能够将列表排序为父类?
答案 0 :(得分:2)
按属性和lambda将排序存储在字典Dictionary<string,Func<DisplayItem,string>> dct
中并传递给方法:
public IEnumerable<DisplayItem> Sort(IEnumerable<DisplayItem> source, string sortBy, Dictionary<string,Func<DisplayItem,string>> dct, SortDirection sortDirection)
{
switch (sortDirection)
{
case SortDirection.Ascending:
return source.OrderBy(x => dct[sortBy]);
case SortDirection.Descending:
return source.OrderByDescending(x => dct[sortBy]);
default:
return null;
}
}
所以你会把你的lambda存储起来:
dct["ProductNumber"] = x => x.SortFields.ProductNumber;
答案 1 :(得分:2)
你可以这个代码, 获得一个函数来选择要排序的字段:
例如,代码将如下所示:
Sort(list, (x) => x.SortFields.ProductNumber, true);
public static IEnumerable<T> Sort(IEnumerable<T> source, Func<T,string> sortBy, bool isUp) where T : new()
{
if(isUp)
{
return source.OrderBy(a => sortBy.Invoke(a));
}
else
{
return source.OrderByDescending(a => sortBy.Invoke(a));
}
}
答案 2 :(得分:0)
这可能会对您有所帮助。
group
使用..
private static readonly MethodInfo OrderByMethod = typeof(Queryable).GetMethods().Single(method => method.Name == "OrderBy" && method.GetParameters().Length == 2);
private static readonly MethodInfo OrderByDescendingMethod = typeof(Queryable).GetMethods().Single(method => method.Name == "OrderByDescending" && method.GetParameters().Length == 2);
static IQueryable<T> OrderByQuery<T>(IQueryable<T> source, string propertyName, SortDirection direction)
{
string[] memberTree = propertyName.Split('.');
Expression ex = null;
Type currentType = typeof(T);
ParameterExpression parameterExpression = Expression.Parameter(currentType);
for (int i = 0; i < memberTree.Length; i++)
{
ex = Expression.Property(ex != null ? ex : parameterExpression, memberTree[i]);
}
LambdaExpression lambda = Expression.Lambda(ex, parameterExpression);
MethodInfo genericMethod =
direction == SortDirection.Descending
? OrderByDescendingMethod.MakeGenericMethod(currentType, ex.Type)
: OrderByMethod.MakeGenericMethod(currentType, ex.Type);
object ret = genericMethod.Invoke(null, new object[] { source, lambda });
return (IQueryable<T>)ret;
}