【发布时间】:2018-02-03 20:01:38
【问题描述】:
我最近在尝试使用 skip 和 take in LINQ 语句时遇到了一个错误。
我的陈述是这样的。
DbConxtext.MyTable.Get(c => c.UserID == id)
.OrderBy(orderProperty).Skip(index).Take(length).ToList();
这给了我这个错误
“OFFSET”附近的语法不正确。\r\n在 FETCH 语句中选项 NEXT 的使用无效
我发现这是因为 OFFSET NEXT 和 FETCH 在 sql server 2008 上不起作用,但我知道我在代码中的其他地方使用了分页,它们都运行良好。
有效的那些和这个有效的区别在于 Skip 和 Take 是 Enumerable 对有效的扩展和 Queryable 的扩展。
因此,将 AsEnumerable() 添加到查询中解决了我的问题。这似乎生成了使用 SELECT TOP(10) 而不是 OFFSET 和 FETCH 的 SQL。
编辑: 再次阅读后,我意识到 AsEnumerable 不会生成不同的 SQL。它将改为执行查询并在内存中执行 Skip Take。
DbConxtext.MyTable.Get(c => c.UserID == id)
.OrderBy(orderProperty).AsEnumerable().Skip(index).Take(length).ToList();
我的问题是使用 Skip 和 Take 作为 Enumerable 与 Queryable 的扩展有什么区别。
以及为什么 EF 决定在这两种情况下生成不同的 SQL。
【问题讨论】:
-
This seemed to generate SQL that uses SELECT TOP(10)它不会做这样的事情。您应该查看生成的实际 SQL,以了解两个查询之间的区别。 -
不同之处在于
Skip和Take将应用于内存而不是DB。基本上你会得到所有的结果,然后过滤到你想要的结果。 -
Skip() 用于忽略像 skip(2) 这样的值,这将忽略前 2 个值。 Take() 用于获取诸如 take(2) 之类的顶部值,这将获取顶部 2 个值。
-
为什么你认为使用AsEnumerable时会生成一个select? AsEnumerable 表示在此处停止生成 SQL。我有兴趣了解为什么人们相信关于编程的错误信息;是什么让你产生了这种信念?
-
@EricLippert 我现在意识到这是不正确的,但我在 LINQPad 4 中运行该查询后得出了这个结论,它有一个功能可以让您查看从语句生成的 SQL,我看到查询正在使用 SELECT TOP。所以我认为这是它在没有给我错误时必须使用的查询。完全忘记了 AsEnumerable 将执行查询。 ://
标签: c# entity-framework linq-to-sql entity-framework-6