2016-09-27 69 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電話。我留給你的是,我不知道數據。