为多个条件按逻辑实现顺序以对最终结果进行排序的问题

Problem in implementing order by logic for multiple condition to order the final results

我有一个网格,其中显示了特定部门的代理列表。这些代理人是 post 出租房屋的房地产代理人。

网格显示 AgentNameNumberofActiveListingsNumberofSoldAndExpiredListings 等基本信息。

现在的要求是默认情况下网格中的列表应根据活动列表降序排列(NumberofActiveListings)。如果多个代理具有相同数量的活动列表,则按 NumberofSoldAndExpiredListings 降序对代理列表进行排序。如果多个代理具有相同数量的 NumberofActiveListingsNumberofSoldAndExpiredListings,则代理列表应按 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>

主要有两种方式

  1. 使用反射(如果列表很大则较慢)
 agents =  agents.OrderBy(o => o.GetType()
                    .GetProperty(model.SortingColumn)
                    .GetValue(o, null)).ToList();
  1. 这样比较快,但需要使用特殊功能
 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();
}