必须在调用跳过之前调用Order by

时间:2015-01-20 16:53:15

标签: c# linq skip

我在尝试执行skip方法时遇到错误。方法' Skip'仅支持LINQ to Entities中的排序输入。方法' OrderBy'必须在方法之前调用'跳过'。

我很清楚必须在调用skip之前调用orderby,并且在调用之前的另一个函数中跳过之前调用它。

AddOrderBy(AdvTitleResults, ColumnNumber, OrderByDesc);

var SearchTitles = AdvTitleResults.Skip(PageNum * NumberOfResults)
                                  .Take(NumberOfResults).ToList();

按功能排序如下所示,默认情况下确保始终分配:

private void AddOrderBy(IQueryable<Title> Results, int ColumnNumber, bool OrderByDesc)
{
    switch (ColumnNumber)
    {
        case 1:
            if (OrderByDesc)
                Results = Results.OrderByDescending(t => t.FK_ContentType);
           else
                Results = Results.OrderBy(t => t.FK_ContentType);
            break;
        case 2:
            if (OrderByDesc)
                Results = Results.OrderByDescending(t => t.TitleFullName);
            else
                Results = Results.OrderBy(t => t.TitleFullName);
            break;
        default:
            if (OrderByDesc)
                Results = Results.OrderByDescending(t => t.ID);
            else
                Results = Results.OrderBy(t => t.ID);
            break;
    }
}

有谁可以解释为什么这不起作用?

1 个答案:

答案 0 :(得分:2)

因为您实际上没有更改AdvTitleResults,所以您正在更改参数的值。您需要使用ref关键字才能使其正常工作:

AddOrderBy(ref AvTitleResults, ColumnNumber, OrderByDesc);

private void AddOrderBy(ref IQueryable<Title> Results, 
                        int ColumnNumber, 
                        bool OrderByDesc)

或者您可以使用LINQ样式并使其成为扩展方法,并返回查询:

private IOrderedQueryable<Title> AddOrderBy(this IQueryable<Title> Results, int ColumnNumber, bool OrderByDesc)
{
    switch (ColumnNumber)
    {
        case 1:
            if (OrderByDesc)
                return Results.OrderByDescending(t => t.FK_ContentType);
           else
                return Results.OrderBy(t => t.FK_ContentType);
            break;
        case 2:
            if (OrderByDesc)
                return Results.OrderByDescending(t => t.TitleFullName);
            else
                return Results.OrderBy(t => t.TitleFullName);
            break;
        default:
            if (OrderByDesc)
                return Results.OrderByDescending(t => t.ID);
            else
                return Results.OrderBy(t => t.ID);
            break;
    }
}

这样你可以像任何其他LINQ方法一样调用它:

var SearchTitles = AdvTitleResults
      .AddOrderBy(ColumnNumber, OrderByDesc)
      .Skip(PageNum * NumberOfResults)
      .Take(NumberOfResults)
      .ToList();

修改

  

不是一个类,这个类不应该默认通过ref吗?

IQueryable<Title>不是一个类,但是它是一个引用类型。但引用类型不是实际通过引用传递。当您传递引用类型时,您的变量所持有的引用值将复制到一个新变量中。它是&#39;是这样的:

string foo = "Foo";
string bar = foo; // copy foo's reference into bar

现在,如果您为bar分配新引用,则无法更改foo

bar = "bar";

因为它们是包含对同一地址的引用的不同变量。但是当你使用ref关键字时,不会复制引用值。相反,你可以认为变量本身已经通过了。那就是最容易理解的方法。我不知道如何用C#语法重现这种行为。