C# 按变量的动态Linq顺序

C# 按变量的动态Linq顺序,c#,linq,C#,Linq,我有一个表,我正在为其编写C#selenium自动化,需要使用动态Linq的帮助。假设我有一个基本的AcctNum、AcctDate和AcctName记录,每个字段都可以由用户排序。他们可以选择AcctNum(asc)、AcctDate(asc),最后选择AcctName(asc) 这将是: var sortedCode = records.OrderBy(r => r.AcctNum) .ThenBy(r => r.AcctDat

我有一个表,我正在为其编写
C#
selenium
自动化,需要使用动态Linq的帮助。假设我有一个基本的
AcctNum
AcctDate
AcctName
记录,每个字段都可以由用户排序。他们可以选择
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();

这可能吗?

如果我理解您的问题,您希望根据每个列和方向(即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
调用输入主排序的优先逻辑,然后是每个次要
调用,然后是by
调用。由你决定,我不知道数据

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

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);
    }
}

您是要求动态方向(上升/下降)还是字段也是动态的?顺便说一句,所谓的动态LINQ(
System.LINQ.Dynamic
)使用字符串。测试用例将为每个字段传递升序或降序变量。我只需要将这些变量中的每一个传递到排序顺序,以便验证排序在UI中是否正常工作。以及
记录的类型是什么
变量-
IQueryable
IEnumerable
?现在记录是IEnumerableThanks Ivan和其他所有人。我感谢你的快速回复。我会看一看,看看是否能消化所有这些:)。Ivan我认为第一个静态需要是公共静态或DeredEnumerable OrderByWithDirection(这是IEnumerable源代码,@Dazed Right,谢谢!(很抱歉,我是为
IQueryable
做的,然后复制/粘贴/调整为
IEnumerable
,但错过了这个).谢谢你在这件事上的帮助.做得很好。
//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();