2016-09-27 77 views
1

我有一张表,我正在写一些C#selenium自动化并需要一些使用Dynamic Linq的帮助。假设我有一个基本的AcctNumAcctDateAcctName记录,每个字段可以由用户排序。他们可以选择AcctNum(asc),AcctDate(asc),最后选择AcctName(asc)。动态Linq订购变量

这将是:

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

但用户也可以选择AcctNum(递减),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(); 

这可能吗?

+0

你问的动态方向(上行/下行)或者这些字段也是动态的?顺便说一句,所谓的动态LINQ('System.Linq.Dynamic')与字符串一起工作。 –

+0

嘿伊万。测试用例将为每个字段传递升序或降序的变量。我只需要将这些变量中的每一个传递给排序顺序,这样我就可以验证这些排序在UI中正常工作。 – Dazed

+0

什么是'记录'变量的**类型** - 'IQueryable '或'IEnumerable '? –

回答

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

感谢Ivan和其他人。我很欣赏这些快速回复。我会看看是否可以消化所有这些:)。 – Dazed

+0

伊万我想先静必须是公共静态IOrderedEnumerable OrderByWithDirection (这IEnumerable的源, – Dazed

+0

@Dazed吧,谢谢!(和抱歉,我是做'的IQueryable ',然后复制/粘贴/调整为'IEnumerable '而错过了)。 –

0

如果我理解你的问题,你要根据每列和方向(即ACCTNUM DESC)

我与伊万Stoev同意,那种LINQ的适用于字符串不以处理您的收藏动态排序与类型的类。

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

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电话。我留给你的是,我不知道数据。