动态Linq按变量排序

本文关键字:排序 变量 Linq 动态 | 更新日期: 2023-09-27 18:09:02

我有一个表,我正在编写一些C# selenium自动化,需要使用动态Linq的一些帮助。假设我有一个基本的AcctNum, AcctDateAcctName记录,每个字段都可以按用户排序。他们可以选择AcctNum (asc), AcctDate (asc)和AcctName (asc)。

就是:

 var sortedCode = records.OrderBy(r => r.AcctNum)
                         .ThenBy(r => r.AcctDate)
                         .ThenBy(r => r.AcctName)
                         .ToList();

但是用户也可以选择AcctNum (desc), AcctDate (asc),最后是AcctName (desc)。

我想做的是使用动态Linq并使每个排序顺序成为一个变量。

比如:

 //passed in values:
 var varAcctNumOrd = "desc";
 var varDateOrd = "asc";
 var varAcctOrd = "desc";
 var sortedCode = records.OrderBy(r => r.AcctNum, varAcctNumOrd)
                         .ThenBy(r => r.AcctDate, varDateOrd)
                         .ThenBy(r => r.AcctNum, varAcctOrd)
                         .ToList();

这可能吗?

动态Linq按变量排序

如果我理解正确的话,以下简单的自定义扩展方法应该可以完成这项工作:

public static class LinqExtensions
{
    public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
        this IEnumerable<TSource> source,
        Func<TSource, TKey> keySelector,
        bool ascending)
    {
        return ascending ? source.OrderBy(keySelector) : source.OrderByDescending(keySelector);
    }
    public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey>(
        this IOrderedEnumerable<TSource> source,
        Func<TSource, TKey> keySelector,
        bool ascending)
    {
        return ascending ? source.ThenBy(keySelector) : source.ThenByDescending(keySelector);
    }
    public static IOrderedQueryable<TSource> OrderBy<TSource, TKey>(
        this IQueryable<TSource> source,
        Expression<Func<TSource, TKey>> keySelector,
        bool ascending)
    {
        return ascending ? source.OrderBy(keySelector) : source.OrderByDescending(keySelector);
    }
    public static IOrderedQueryable<TSource> ThenBy<TSource, TKey>(
        this IOrderedQueryable<TSource> source,
        Expression<Func<TSource, TKey>> keySelector,
        bool ascending)
    {
        return ascending ? source.ThenBy(keySelector) : source.ThenByDescending(keySelector);
    }
}

的用法是:

//passed in values:
var varAcctNumOrd = "desc";
var varDateOrd = "asc";
var varAcctOrd = "desc";
var sortedCode = records.OrderBy(r => r.AcctNum, varAcctNumOrd != "desc")
                        .ThenBy(r => r.AcctDate, varDateOrd != "desc")
                        .ThenBy(r => r.AcctNum, varAcctOrd != "desc")
                        .ToList();

如果我理解你的问题,你想根据每个列和方向(即AcctNum desc)处理你的集合的动态排序

我同意Ivan Stoev的观点,这种linq适用于字符串而不是类型化的类。

您可以使用AsQueryable()解决方案来解决这个问题。

在调用ToList之前,由于IQueryable接口,正在构建查询。只需使用一些布尔值来确定方向并进行排序:

var recordsToSort = records.AsQueryable();
if (isByAcctNum)
{
   recordsToSort = recordsToSort.OrderBy(r => r.AcctNum);
   if (isByDate)
      recordsToSort =  recorsToSort.ThenBy(r => r.AcctDate)
   ....
}
else
{
    ....
}
return recordsToSort.ToList()

您需要为第一个OrderBy调用放入主排序的优先级逻辑,然后是每个次要ThenBy调用。我把这个留给你们,我不知道数据。