动态Linq按变量排序

时间:2016-09-27 20:09:21

标签: c# linq

我有一个表格,我正在编写一些C# selenium自动化,并需要使用Dynamic Linq的帮助。我们说我有一个基本的AcctNumAcctDateAcctName记录,每个字段都可以由用户排序。他们可以选择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)。

我想要做的是使用Dynamic 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();

这可能吗?

3 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:0)

如果我理解您的问题,您希望根据每个列和方向处理您的收藏的动态排序(即AcctNum desc)

我同意Ivan Stoev的观点,那种linq适用于不使用类型类的字符串。

您可以使用AsQueryable()解决方案解决此问题。

答案 2 :(得分:0)

在调用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调用。我留给你的是,我不知道这些数据。