![](/img/trans.png)
[英]What collection should I use in a linq-to-sql query? Queryable vs Enumerable vs List
[英]Skip() and Take() as Enumerable vs as Queryable
我最近在嘗試使用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。 相反,它將執行查詢並在內存中執行“跳過接管”。
DbConxtext.MyTable.Get(c => c.UserID == id)
.OrderBy(orderProperty).AsEnumerable().Skip(index).Take(length).ToList();
我的問題是,使用“跳過”和“采用作為Enumerable與Queryable的擴展”之間有什么區別?
以及為什么EF決定在這兩種情況之間生成不同的SQL。
使用
Skip
和Take
asEnumerable
與Queryable
擴展之間有什么區別?
當您在實現IQueryable
的類型上調用Skip
或Take
時,將綁定Queryable
擴展方法,並且基礎的Linq提供程序(例如Linq-to-Entities)將處理Skip
和/或Take
並將其轉換為基礎的命令數據提供者(例如SQL語句)。 直到運行時,才知道提供程序是實際支持它們還是正確處理它們。
當您在實現IEnumerable
的類型上調用它們(但不是IQueryable
)時,將綁定Enumerable
擴展方法,該方法僅處理Queryable
查詢生成的內存集合中的命令。
EF為什么決定在兩種情況下生成不同的SQL。
在第二種情況下,生成的SQL查詢僅合並命令,直到您注入AsEnumerable()
為止。 這就是EF提供程序所能看到的全部。 從那時起,這些命令將綁定到Enumerable
擴展方法,並將在內存中處理其余命令。
這似乎生成使用SELECT TOP(10)的SQL。
我對此表示高度懷疑。 應該發生的是,SQL查詢將返回所有記錄,但是Take
生成的內存中迭代器將僅返回前十個。
如果要為SQL 2008數據庫正確處理“跳過”和“取走”,請參閱此問題以獲取替代解決方案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.