【问题标题】:The method 'OrderBy' must be called before the method 'Skip' Exception方法 'OrderBy' 必须在方法 'Skip' 之前调用 异常
【发布时间】:2012-07-20 13:24:36
【问题描述】:

我试图使用MvcjQgrid 实现jQgrid,但我遇到了这个异常。

System.NotSupportedException was unhandled by user code
  Message=The method 'Skip' is only supported for sorted input in LINQ to Entities. The method 'OrderBy' must be called before the method 'Skip'.

虽然在 Skip 方法之前使用了 OrdeyBy,但为什么会产生异常?怎么解决?

我在控制器中遇到了异常:

public ActionResult GridDataBasic(GridSettings gridSettings)
        {          
            var jobdescription = sm.GetJobDescription(gridSettings);
            var totalJobDescription = sm.CountJobDescription(gridSettings);

            var jsonData = new
            {
                total = totalJobDescription / gridSettings.PageSize + 1,
                page = gridSettings.PageIndex,
                records = totalJobDescription,
                rows = (
                    from j in jobdescription
                    select new
                    {
                        id = j.JobDescriptionID,
                        cell = new[] 
                    { 
                        j.JobDescriptionID.ToString(), 
                        j.JobTitle,
                        j.JobType.JobTypeName,
                        j.JobPriority.JobPriorityName,
                        j.JobType.Rate.ToString(),
                        j.CreationDate.ToShortDateString(),
                         j.JobDeadline.ToShortDateString(),

                    }
                    }).ToArray()
            };
            return Json(jsonData, JsonRequestBehavior.AllowGet);
        }

GetJobDescription 方法CountJobDescription 方法

public int CountJobDescription(GridSettings gridSettings)
        {
            var jobdescription = _dataContext.JobDescriptions.AsQueryable();

            if (gridSettings.IsSearch)
            {
                jobdescription = gridSettings.Where.rules.Aggregate(jobdescription, FilterJobDescription);
            }
            return jobdescription.Count();
        }

        public IQueryable<JobDescription> GetJobDescription(GridSettings gridSettings)
        {
            var jobdescription = orderJobDescription(_dataContext.JobDescriptions.AsQueryable(), gridSettings.SortColumn, gridSettings.SortOrder);

            if (gridSettings.IsSearch)
            {
                jobdescription = gridSettings.Where.rules.Aggregate(jobdescription, FilterJobDescription);
            }

            return jobdescription.Skip((gridSettings.PageIndex - 1) * gridSettings.PageSize).Take(gridSettings.PageSize);
        }

最后是 FilterJobDescription 和 OrderJobDescription

private static IQueryable<JobDescription> FilterJobDescription(IQueryable<JobDescription> jobdescriptions, Rule rule)
        {
            if (rule.field == "JobDescriptionID")
            {
                int result;
                if (!int.TryParse(rule.data, out result))
                    return jobdescriptions;
                return jobdescriptions.Where(j => j.JobDescriptionID == Convert.ToInt32(rule.data));

            }

// Similar Statements

            return jobdescriptions;
        }



private IQueryable<JobDescription> orderJobDescription(IQueryable<JobDescription> jobdescriptions, string sortColumn, string sortOrder)
        {
            if (sortColumn == "JobDescriptionID")
                return (sortOrder == "desc") ? jobdescriptions.OrderByDescending(j => j.JobDescriptionID) : jobdescriptions.OrderBy(j => j.JobDescriptionID);

            return jobdescriptions;
        }

【问题讨论】:

  • 但你并不总是订购,只有sortColumn == "JobDescriptionID",对吗?
  • 这有关系吗?顺便说一句,我还有其他几个订单声明。

标签: asp.net-mvc-3 entity-framework linq-to-entities mvcjqgrid


【解决方案1】:

这个例外意味着如果您应用Skip,您总是需要一个排序的输入,同样在用户没有点击要排序的列的情况下。我可以想象,当您第一次打开网格视图时,用户甚至可以单击列标题之前没有指定任何排序列。为了捕捉这种情况,我建议在没有给出其他排序标准时定义一些您想要的默认排序,例如:

switch (sortColumn)
{
    case "JobDescriptionID":
        return (sortOrder == "desc")
            ? jobdescriptions.OrderByDescending(j => j.JobDescriptionID)
            : jobdescriptions.OrderBy(j => j.JobDescriptionID);

    case "JobDescriptionTitle":
        return (sortOrder == "desc")
            ? jobdescriptions.OrderByDescending(j => j.JobDescriptionTitle)
            : jobdescriptions.OrderBy(j => j.JobDescriptionTitle);

    // etc.

    default:
        return jobdescriptions.OrderBy(j => j.JobDescriptionID);
}

编辑

根据您的评论,关于您的后续问题:您不能在 LINQ to Entities 查询中使用ToString()。下一个问题是您不能在查询中创建string 数组。我建议使用它们的原生类型从数据库加载数据,然后在内存中转换为字符串(以及字符串数组):

rows = (from j in jobdescription
        select new
        {
            JobDescriptionID = j.JobDescriptionID,
            JobTitle = j.JobTitle,
            JobTypeName = j.JobType.JobTypeName,
            JobPriorityName = j.JobPriority.JobPriorityName,
            Rate = j.JobType.Rate,
            CreationDate = j.CreationDate,
            JobDeadline = j.JobDeadline
        })
        .AsEnumerable() // DB query runs here, the rest is in memory
        .Select(a => new
        {
            id = a.JobDescriptionID,
            cell = new[] 
            { 
                a.JobDescriptionID.ToString(), 
                a.JobTitle,
                a.JobTypeName,
                a.JobPriorityName,
                a.Rate.ToString(),
                a.CreationDate.ToShortDateString(),
                a.JobDeadline.ToShortDateString()
            }
        })
        .ToArray()

【讨论】:

  • 该异常现已消失。但是在控制器中遇到了新的异常LINQ to Entities does not recognize the method 'System.String ToString()' method, and this method cannot be translated into a store expression.现在如何将JobDescriptionID和其他属性转换为字符串呢?
  • @aneal:见我的编辑。 (它实际上与您最初的问题无关。)
【解决方案2】:

在使用 Adam Anderson 中的一些代码进行排序后,我遇到了相同类型的问题,该代码接受了 OrderBy 中的通用排序字符串。

得到这个异常后,我做了很多研究,发现非常聪明的解决方法:

var query = SelectOrders(companyNo, sortExpression);

return Queryable.Skip(query, iStartRow).Take(iPageSize).ToList();

希望有帮助!

SP

【讨论】:

  • 我的解决方案中有那个通用实现,尝试了你的修复,但它不起作用,顺便说一下当前的更改会做什么
猜你喜欢
  • 2014-10-05
  • 2012-06-28
  • 2014-03-09
  • 1970-01-01
  • 2014-05-13
  • 2019-06-08
  • 2013-07-24
相关资源
最近更新 更多