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

Posted

技术标签:

【中文标题】为多个条件实现按逻辑排序以对最终结果进行排序的问题【英文标题】:Problem in implementing order by logic for multiple condition to order the final results 【发布时间】:2021-12-13 04:05:24 【问题描述】:

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

网格显示AgentNameNumberofActiveListingsNumberofSoldAndExpiredListings 等基本信息。

现在要求默认情况下,网格中的列表应根据活动列表按降序排序(NumberofActiveListings)。如果多个代理具有相同数量的活动列表,则将代理列表按NumberofSoldAndExpiredListings 降序排列。如果多个代理具有相同数量的NumberofActiveListingsNumberofSoldAndExpiredListings,则代理列表应按Name 升序排列。

此外,用户可以单击网格上的单个列,数据将根据该列进行排序。

下面是保存最终结果的 DTO 类:

     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 升序排序。

谁能指导我按照逻辑顺序实现这个要求?

【问题讨论】:

【参考方案1】:

至于按多列排序,请查看与初始 .OrderBy() 和 .OrderByDescending() 结合使用的 .ThenBy() 和 .ThenByDescending() 函数。

关于动态选择要排序的列,请看Dynamic LINQ OrderBy on IEnumerable<T> / IQueryable<T>。

【讨论】:

但是我对这种逻辑感到困惑,如果 NumberofActiveListings 相同,则按 NumberofSoldAndExpiredListings 排序,如果 NumberofSoldAndExpiredListings 相同,则按 AgentName 升序排序? 你没有。您只需按优先顺序列出排序字段: .OrderBy(a => a.NumberofActiveListings) .ThenBy(a => a.NumberofSoldAndExpiredListings) .ThenBy(a => a.AgentName) ^ 这...我误读了这个问题。如果您只想默认按活动列表排序,那么如果相同,按 Sold 和 Expired 排序,您需要上述内容。如果您有指定的排序列,则可以使用它代替此默认排序,或者可以使用ThenBy 条件将其附加到它。【参考方案2】:

主要有两种方式

    使用反射(如果列表很大,则速度较慢)
 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();

【讨论】:

但是我对这种逻辑感到困惑,如果 NumberofActiveListings 相同,则按 NumberofSoldAndExpiredListings 排序,如果 NumberofSoldAndExpiredListings 相同,则按 AgentName 升序排序? @ILove*** 很抱歉,但我不明白“如果 NumberofActiveListings 相同”是什么意思?可以发个例子吗?

以上是关于为多个条件实现按逻辑排序以对最终结果进行排序的问题的主要内容,如果未能解决你的问题,请参考以下文章

Linux——MySQL高阶语句杂而精

MongoDB 条件查询和排序

为啥当我实现以 2^20 为底的基数排序以对大小为 500 万的数组进行排序时,该程序会陷入无限循环?

Python:按多个条件显示排序字典

Excel多条件自定义排序

mysql多个相同类型字段排序问题