方法 'OrderBy' 必须在方法 'Skip' 之前调用 异常
Posted
技术标签:
【中文标题】方法 \'OrderBy\' 必须在方法 \'Skip\' 之前调用 异常【英文标题】: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"
,对吗?
这有关系吗?顺便说一句,我还有其他几个订单声明。
【参考方案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
【讨论】:
我的解决方案中有那个通用实现,尝试了你的修复,但它不起作用,顺便说一下当前的更改会做什么以上是关于方法 'OrderBy' 必须在方法 'Skip' 之前调用 异常的主要内容,如果未能解决你的问题,请参考以下文章
NHibernte 4.0.3版本中,使用Queryover().Where().OrderBy().Skip().Take()方法分页获取数据失败
MongoDB limit 选取 skip跳过 sort排序 方法
LINQ 查询添加 orderby 使 Skip 和 Take 不起作用 Linqpad
具有实体框架并使用 orderby 和 skip/take 的规范模式
在对象 (ROOT_QUERY) 上找不到字段 allProjects("first":5,"skip":0,"orderBy":"