动态Linq按变量排序
本文关键字:排序 变量 Linq 动态 | 更新日期: 2023-09-27 18:09:02
我有一个表,我正在编写一些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();
这可能吗?
如果我理解正确的话,以下简单的自定义扩展方法应该可以完成这项工作:
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
调用。我把这个留给你们,我不知道数据。