为多个条件按逻辑实现顺序以对最终结果进行排序的问题
Problem in implementing order by logic for multiple condition to order the final results
我有一个网格,其中显示了特定部门的代理列表。这些代理人是 post 出租房屋的房地产代理人。
网格显示 AgentName
、NumberofActiveListings
、NumberofSoldAndExpiredListings
等基本信息。
现在的要求是默认情况下网格中的列表应根据活动列表降序排列(NumberofActiveListings)。如果多个代理具有相同数量的活动列表,则按 NumberofSoldAndExpiredListings
降序对代理列表进行排序。如果多个代理具有相同数量的 NumberofActiveListings
和 NumberofSoldAndExpiredListings
,则代理列表应按 Name
升序排序。
此外,用户可以单击网格上的单个列,数据将根据该列进行排序。
下面是保存最终结果的 DTO class:
public class AgentResultDto
{
public int AgentId { get; set; }
public string AgentName { get; set; }
public int NumberofActiveListings { get; set; }
public int NumberofSoldAndExpiredListings { get; set; }
}
public class GridviewInput
{
public string SortingColumn { get; set; } //hold the column name user will click on to sort the data
//other params
}
public virtual async Task<AgentResultDto> GetAgents(GridviewInput model)
{
List<AgentResultDto> agents = new List<AgentResultDto>();
//logic to populate agent list
agents = agents.OrderBy(model.SortingColumn).ToList();
}
但在这里我对如何指定条件感到困惑,如果 NumberofActiveListings 相同则按 NumberofSoldAndExpiredListings
排序,如果 NumberofSoldAndExpiredListings
相同则按 AgentName
升序排序。
谁能指导我按逻辑顺序实现这个需求?
至于按多列排序,请查看与初始 .OrderBy() 和 .OrderByDescending() 结合使用的 .ThenBy() 和 .ThenByDescending() 函数。
关于动态选择要排序的列,看一下Dynamic LINQ OrderBy on IEnumerable<T> / IQueryable<T>。
主要有两种方式
- 使用反射(如果列表很大则较慢)
agents = agents.OrderBy(o => o.GetType()
.GetProperty(model.SortingColumn)
.GetValue(o, null)).ToList();
- 这样比较快,但需要使用特殊功能
var columnGetter = CreateGetter(quotes[0].GetType(), model.SortingColumn);
quotes = quotes .OrderBy(o => columnGetter(o)).ToList();
public static Func<object, object> CreateGetter(Type runtimeType, string propertyName)
{
var propertyInfo = runtimeType.GetProperty(propertyName);
var obj = Expression.Parameter(typeof(object), "obj");
var objT = Expression.TypeAs(obj, runtimeType);
var property = Expression.Property(objT, propertyInfo);
var convert = Expression.TypeAs(property, typeof(object));
return (Func<object, object>)Expression.Lambda(convert, obj).Compile();
}
我有一个网格,其中显示了特定部门的代理列表。这些代理人是 post 出租房屋的房地产代理人。
网格显示 AgentName
、NumberofActiveListings
、NumberofSoldAndExpiredListings
等基本信息。
现在的要求是默认情况下网格中的列表应根据活动列表降序排列(NumberofActiveListings)。如果多个代理具有相同数量的活动列表,则按 NumberofSoldAndExpiredListings
降序对代理列表进行排序。如果多个代理具有相同数量的 NumberofActiveListings
和 NumberofSoldAndExpiredListings
,则代理列表应按 Name
升序排序。
此外,用户可以单击网格上的单个列,数据将根据该列进行排序。
下面是保存最终结果的 DTO class:
public class AgentResultDto
{
public int AgentId { get; set; }
public string AgentName { get; set; }
public int NumberofActiveListings { get; set; }
public int NumberofSoldAndExpiredListings { get; set; }
}
public class GridviewInput
{
public string SortingColumn { get; set; } //hold the column name user will click on to sort the data
//other params
}
public virtual async Task<AgentResultDto> GetAgents(GridviewInput model)
{
List<AgentResultDto> agents = new List<AgentResultDto>();
//logic to populate agent list
agents = agents.OrderBy(model.SortingColumn).ToList();
}
但在这里我对如何指定条件感到困惑,如果 NumberofActiveListings 相同则按 NumberofSoldAndExpiredListings
排序,如果 NumberofSoldAndExpiredListings
相同则按 AgentName
升序排序。
谁能指导我按逻辑顺序实现这个需求?
至于按多列排序,请查看与初始 .OrderBy() 和 .OrderByDescending() 结合使用的 .ThenBy() 和 .ThenByDescending() 函数。
关于动态选择要排序的列,看一下Dynamic LINQ OrderBy on IEnumerable<T> / IQueryable<T>。
主要有两种方式
- 使用反射(如果列表很大则较慢)
agents = agents.OrderBy(o => o.GetType()
.GetProperty(model.SortingColumn)
.GetValue(o, null)).ToList();
- 这样比较快,但需要使用特殊功能
var columnGetter = CreateGetter(quotes[0].GetType(), model.SortingColumn);
quotes = quotes .OrderBy(o => columnGetter(o)).ToList();
public static Func<object, object> CreateGetter(Type runtimeType, string propertyName)
{
var propertyInfo = runtimeType.GetProperty(propertyName);
var obj = Expression.Parameter(typeof(object), "obj");
var objT = Expression.TypeAs(obj, runtimeType);
var property = Expression.Property(objT, propertyInfo);
var convert = Expression.TypeAs(property, typeof(object));
return (Func<object, object>)Expression.Lambda(convert, obj).Compile();
}