我在字符串中有“按属性排序”的名称。我需要使用Lambda/Linq对对象列表进行排序。
Ex:
public class Employee
{
public string FirstName {set; get;}
public string LastName {set; get;}
public DateTime DOB {set; get;}
}
public void Sort(ref List<Employee> list, string sortBy, string sortDirection)
{
//Example data:
//sortBy = "FirstName"
//sortDirection = "ASC" or "DESC"
if (sortBy == "FirstName")
{
list = list.OrderBy(x => x.FirstName).toList();
}
}
与其使用一堆if来检查字段名(sortBy),还有一种更干净的排序方式吗
排序是否知道数据类型?
不幸的是,Rashack提供的解决方案不适用于值类型(int、enum等)。
对于任何类型的属性,这是我发现的解决方案:
public static Expression<Func<T, object>> GetLambdaExpressionFor<T>(this string sortColumn)
{
var type = typeof(T);
var parameterExpression = Expression.Parameter(type, "x");
var body = Expression.PropertyOrField(parameterExpression, sortColumn);
var convertedBody = Expression.MakeUnary(ExpressionType.Convert, body, typeof(object));
var expression = Expression.Lambda<Func<T, object>>(convertedBody, new[] { parameterExpression });
return expression;
}
不幸的是,Rashack提供的解决方案不适用于值类型(int、enum等)。
对于任何类型的属性,这是我发现的解决方案:
public static Expression<Func<T, object>> GetLambdaExpressionFor<T>(this string sortColumn)
{
var type = typeof(T);
var parameterExpression = Expression.Parameter(type, "x");
var body = Expression.PropertyOrField(parameterExpression, sortColumn);
var convertedBody = Expression.MakeUnary(ExpressionType.Convert, body, typeof(object));
var expression = Expression.Lambda<Func<T, object>>(convertedBody, new[] { parameterExpression });
return expression;
}
如果你得到排序列名和排序方向为字符串,并且不想使用switch或If \else语法来确定列,那么这个例子可能对你很有趣:
private readonly Dictionary<string, Expression<Func<IuInternetUsers, object>>> _sortColumns =
new Dictionary<string, Expression<Func<IuInternetUsers, object>>>()
{
{ nameof(ContactSearchItem.Id), c => c.Id },
{ nameof(ContactSearchItem.FirstName), c => c.FirstName },
{ nameof(ContactSearchItem.LastName), c => c.LastName },
{ nameof(ContactSearchItem.Organization), c => c.Company.Company },
{ nameof(ContactSearchItem.CustomerCode), c => c.Company.Code },
{ nameof(ContactSearchItem.Country), c => c.CountryNavigation.Code },
{ nameof(ContactSearchItem.City), c => c.City },
{ nameof(ContactSearchItem.ModifiedDate), c => c.ModifiedDate },
};
private IQueryable<IuInternetUsers> SetUpSort(IQueryable<IuInternetUsers> contacts, string sort, string sortDir)
{
if (string.IsNullOrEmpty(sort))
{
sort = nameof(ContactSearchItem.Id);
}
_sortColumns.TryGetValue(sort, out var sortColumn);
if (sortColumn == null)
{
sortColumn = c => c.Id;
}
if (string.IsNullOrEmpty(sortDir) || sortDir == SortDirections.AscendingSort)
{
contacts = contacts.OrderBy(sortColumn);
}
else
{
contacts = contacts.OrderByDescending(sortColumn);
}
return contacts;
}
基于使用Dictionary的解决方案,通过表达式>和它的键字符串连接排序列所需的字典。