Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用排序表达式列表对查询表进行排序_C#_Linq_Sorting_Repository Pattern - Fatal编程技术网

C# 使用排序表达式列表对查询表进行排序

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

我正在构建一个存储库,希望能够将一个排序列表传递给函数,以便以正确的顺序接收实体并可能分页

我发现,如果对每个排序表达式使用反向排序列表和Orderby,linq将正确排序

        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()方法。见张贴: