Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/17.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
Vb.net 在循环中添加多个OrderBy语句的Linq查询_Vb.net_Linq_Sql Order By - Fatal编程技术网

Vb.net 在循环中添加多个OrderBy语句的Linq查询

Vb.net 在循环中添加多个OrderBy语句的Linq查询,vb.net,linq,sql-order-by,Vb.net,Linq,Sql Order By,我在一个webservice中有一个方法,它有一个参数,用户可以用它来决定他们想要如何对结果排序。这是一个列表(字符串),其中按字段的排序顺序列出了字段的名称 我知道我通常可以通过执行以下操作对多个列进行排序 Dim test = Bars.OrderBy(Function(x) x.Foo) _ .ThenBy(Function(x) x.Bar) _ .ThenBy(Function(x) x.Test) 但是在这种情况下,这将不

我在一个webservice中有一个方法,它有一个参数,用户可以用它来决定他们想要如何对结果排序。这是一个
列表(字符串)
,其中按字段的排序顺序列出了字段的名称

我知道我通常可以通过执行以下操作对多个列进行排序

Dim test = Bars.OrderBy(Function(x) x.Foo) _
               .ThenBy(Function(x) x.Bar) _
               .ThenBy(Function(x) x.Test)
但是在这种情况下,这将不起作用,因为我无法链接
ThenBy
函数,因为我正在循环中添加排序顺序。要使用
ThenBy
我需要一个
IOrderedQueryable
集合。这就是我希望它工作的方式

Dim sortColumns = {"Foo", "Bar", "Test"}
Dim query = From b in Bars
For each column in sortColumns
    Select Case column
        Case "Foo"
            query = query.Orderby(Function(x) x.Foo)
        Case "Bar"
            query = query.Orderby(Function(x) x.Bar)
        Case "Test"
            query = query.Orderby(Function(x) x.Test)
    End Select
Next

Dim result = query.Select(Function(x) x.x).ToList()
Return result
这当然行不通,因为
OrderBy
将取代以前的任何订购。我能想到的唯一解决方案是首先对其他变量的列表进行排序,这样我已经有了一个
IOrderedQueryable
集合,但这似乎是错误的方法

Dim bars As New List(Of Bar)
Dim sortColumns = {"Foo", "Bar", "Test"}
Dim query = bars.Select(Function(x) New With {.Temp = 1, .x = x}) _
                .OrderBy(Function(x) x.Temp)

For Each column In sortColumns
    Select Case column
        Case "Foo"
            query = query.ThenBy(Function(x) x.x.Foo)
        Case "Bar"
            query = query.ThenBy(Function(x) x.x.Bar)
        Case "Test"
            query = query.ThenBy(Function(x) x.x.Test)
    End Select
Next

Dim result = query.Select(Function(x) x.x).ToList()
Return result    

您可以编写自己的扩展方法
orderbyortenby
,该方法检查值是否已经是
IOrderedQueryable
,如果是,则使用
ThenBy
,否则使用
OrderBy
。有点臭,但不是很难做到

编辑:C#样本(未测试):

公共静态类QueryableOrdering
{
公共静态IOrderedQueryable OrderByOrThenBy
(这是一个可靠的来源,
表达式排序)
{
if(source==null)
{
抛出新的ArgumentNullException(“源”);
}
if(排序==null)
{
抛出新的ArgumentNullException(“排序”);
}
var ordered=源作为IOrderedQueryable;
return ordered==null?source.OrderBy(排序)
:订购。然后由(订购);
}
}

C#示例就可以了,我可以自己进行转换。@FreekBuurman:添加工作的VB.NET代码作为答案,并参考Jon的答案。“OrderBy将替换以前的任何订购”。不真实。OrderBy保留先前的排序。。。意思:这是一个稳定的重新排序。也就是说,它使用先前的排序来打破当前排序中的关系。因此:OrderBy(Foo).ThenBy(Bar).ThenBy(Test)与OrderBy(Test).OrderBy(Bar).OrderBy(Foo)相同
public static class QueryableOrdering
{
    public static IOrderedQueryable<TElement> OrderByOrThenBy<TElement, TKey>
        (this IQueryable<TElement> source,
         Expression<Func<TElement, TKey>> ordering)
    {
        if (source == null)
        {
            throw new ArgumentNullException("source");
        }
        if (ordering == null)
        {
            throw new ArgumentNullException("ordering");
        }
        var ordered = source as IOrderedQueryable<TElement>;
        return ordered == null ? source.OrderBy(ordering)
                               : ordered.ThenBy(ordering);
    }
}