首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >跳过()并接受()作为可枚举的vs作为Queryable

跳过()并接受()作为可枚举的vs作为Queryable
EN

Stack Overflow用户
提问于 2017-08-25 17:51:14
回答 1查看 2.1K关注 0票数 1

最近,我在尝试使用skip并接受LINQ语句时遇到了一个错误。

我的陈述是这样的。

代码语言:javascript
复制
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。相反,它将执行查询并在内存中执行跳取。

代码语言:javascript
复制
DbConxtext.MyTable.Get(c => c.UserID == id)
    .OrderBy(orderProperty).AsEnumerable().Skip(index).Take(length).ToList();

我的问题是,使用Skip和接受作为可枚举的vs Queryable的扩展有什么区别。

为什么EF决定在这两种情况下生成不同的SQL。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-08-25 18:07:52

使用SkipTake作为EnumerableQueryable的扩展有什么区别?

当对实现Skip的类型调用IQueryableTake时,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获取备用解决方案。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45886998

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档