最近,我在尝试使用skip并接受LINQ语句时遇到了一个错误。
我的陈述是这样的。
DbConxtext.MyTable.Get(c => c.UserID == id)
.OrderBy(orderProperty).Skip(index).Take(length).ToList();这让我犯了这个错误
在“偏移”附近不正确的语法。\r\n在FETCH语句中下一个选项的有效用法
我发现这是因为偏移NEXT和FETCH在sql server 2008上不起作用,但我知道我在代码中使用的是其他地方的分页,它们都很好。
与此不同的是,、Skip、和Take是可枚举的扩展,是工作的可枚举的扩展,而Queryable则是不工作的可查询的扩展。
因此,将AsEnumerable()添加到查询中为我解决了这个问题。这似乎生成了使用、SELECT(10)而不是偏移和FETCH的SQL。
编辑:再读一遍之后,我意识到AsEnumerable不会生成不同的SQL。相反,它将执行查询并在内存中执行跳取。
DbConxtext.MyTable.Get(c => c.UserID == id)
.OrderBy(orderProperty).AsEnumerable().Skip(index).Take(length).ToList();我的问题是,使用Skip和接受作为可枚举的vs Queryable的扩展有什么区别。
为什么EF决定在这两种情况下生成不同的SQL。
发布于 2017-08-25 18:07:52
使用
Skip和Take作为Enumerable与Queryable的扩展有什么区别?
当对实现Skip的类型调用IQueryable或Take时,Queryable扩展方法将被绑定,底层Linq提供者(例如Linq到实体)将处理Skip和/或Take,并将其转换为底层数据提供程序的命令(例如,SQL语句)。提供程序是否实际支持它们或正确地处理它们,直到运行时才会知道。
当您在实现IEnumerable (但不是IQueryable)的类型上调用它们时,将绑定Enumerable扩展方法,后者只处理由Queryable查询生成的内存中集合上的命令。
为什么EF决定在这两种情况之间生成不同的SQL。
在第二种情况下,生成的SQL查询只在注入AsEnumerable()之前合并这些命令。EF提供商看到的就是这些。从那时起,这些命令将绑定到Enumerable扩展方法,并将处理内存中的其余命令。
这似乎生成了使用SELECT TOP(10)的SQL。
我对此深表怀疑。应该发生的是,SQL查询将返回所有记录,但是由Take生成的内存中迭代器只返回前十个记录。
如果希望SQL 2008数据库正确地处理跳过和取取,请参阅this question获取备用解决方案。
https://stackoverflow.com/questions/45886998
复制相似问题