C# 使用排序表达式列表对查询表进行排序
我正在构建一个存储库,希望能够将一个排序列表传递给函数,以便以正确的顺序接收实体并可能分页 我发现,如果对每个排序表达式使用反向排序列表和Orderby,linq将正确排序C# 使用排序表达式列表对查询表进行排序,c#,linq,sorting,repository-pattern,C#,Linq,Sorting,Repository Pattern,我正在构建一个存储库,希望能够将一个排序列表传递给函数,以便以正确的顺序接收实体并可能分页 我发现,如果对每个排序表达式使用反向排序列表和Orderby,linq将正确排序 foreach (var s in sorts.Reverse()) { query = query.OrderBy(s); } 然而,在测试排序方向的添加时,我发现它只接受第一个排序方向,并且似乎将该方向应用于每个排序 private voi
foreach (var s in sorts.Reverse())
{
query = query.OrderBy(s);
}
然而,在测试排序方向的添加时,我发现它只接受第一个排序方向,并且似乎将该方向应用于每个排序
private void applySorts(ref IQueryable<TEntity> query, Dictionary<Expression<Func<TEntity, dynamic>>, string> sorts)
{
if (sorts != null)
{
foreach (var s in sorts.Reverse())
{
Expression<Func<TEntity, dynamic>> expr = s.Key;
string dir = s.Value;
if (dir == "d")
{
query = query.OrderByDescending(expr);
}
else
{
query = query.OrderBy(expr);
}
}
}
}
private void applySorts(参考可查询查询、字典排序)
{
if(排序!=null)
{
foreach(sorts.Reverse()中的var s)
{
表达式expr=s.Key;
字符串dir=s.值;
如果(dir==“d”)
{
query=query.OrderByDescending(expr);
}
其他的
{
query=query.OrderBy(expr);
}
}
}
}
我最初尝试在第一次排序时使用OrderBy,然后切换到ThenBy,但这是不可能的,因为ThenBy需要一种IOrderedQueryable类型
我想指出的是字典的使用可能不是最好的,如果你有任何更好的想法请分享。然而,我只是想让它运行起来,看看事情进展如何
我正在使用C#、Linq和实体框架
提前感谢您抽出时间
更新:不幸的是,我发现这不支持对数字进行排序。错误(无法将类型“System.Int32”强制转换为类型“System.Object”)您可以使用ThenBy()
方法链接筛选器,如下所示:
bool first = true;
foreach(var s in sorts)
{
query = first ? query.OrderBy(s) : query.ThenBy(s);
}
// It will became like query.OrderBy(a => a.A).ThenBy(a => a.B).ThenBy(a => a.C)...
如果您知道要对其进行排序的属性,还可以在LINQ查询中使用多列排序:
var result = (from row in list
orderby row.A, row.B, row.C
select row).ToList();
从语法上讲,您只需要一个IOrderedQueryable类型的临时变量 我想尝试一下:
private void applySorts(ref IQueryable<TEntity> query, Dictionary<Expression<Func<TEntity, dynamic>>, string> sorts)
{
if (sorts != null)
{
IOrderedQueryable<TEntity> tempQuery = null;
bool isFirst = true;
foreach (var s in sorts.Reverse())
{
Expression<Func<TEntity, dynamic>> expr = s.Key;
string dir = s.Value;
if (first)
{
first = false;
if (dir == "d")
{
tempQuery = query.OrderByDescending(expr);
}
else
{
tempQuery = query.OrderBy(expr);
}
}
else
{
if (dir == "d")
{
tempQuery = tempQuery.ThenByDescending(expr);
}
else
{
tempQuery = tempQuery.ThenBy(expr);
}
}
}
query = tempQuery;
}
}
private void applySorts(参考可查询查询、字典排序)
{
if(排序!=null)
{
IOrderedQueryable tempQuery=null;
bool isFirst=true;
foreach(sorts.Reverse()中的var s)
{
表达式expr=s.Key;
字符串dir=s.值;
如果(第一)
{
第一个=假;
如果(dir==“d”)
{
tempQuery=query.OrderByDescending(expr);
}
其他的
{
tempQuery=query.OrderBy(expr);
}
}
其他的
{
如果(dir==“d”)
{
tempQuery=tempQuery.ThenByDescending(expr);
}
其他的
{
tempQuery=tempQuery.ThenBy(expr);
}
}
}
query=tempQuery;
}
}
编辑:
上述解决方案的关键是IOrderedQueryable是IQueryable
我自己没试过。然而,我要强调的是,这只是一个语法上的解决方案
var query=query.OrderBy(排序[0])代码>无法编译。@hvd好的,我没有注意到它是一本字典。:)然后他可以将循环更改为foreach
,而不是像他那样的for
。只需对第一个排序表达式应用OrderBy()
,然后对所有其他表达式应用OrderBy()
。呵呵,我的意思是,你不能有一个与参数同名的局部变量,但是的,也是这样。:)在您编辑的版本中,query.ThenBy
将不会编译,query
具有类型IQueryable
。您与第一个版本更接近,您确实需要一个单独的变量,您只需要给它一个不同的名称。我将使用SortedDictionary,其键是继承IComparable的自定义类,IComparable实现了CompareTo()方法。见张贴: