2017-04-14 65 views
0
  1. 如果IQueryable接口執行服務器查詢表達式,而不是像獲取所有IEnumerable記錄,爲什麼IQueryableIEnumerable替代它可以更快,更高效?IQueryable與IEnumerable:IQueryable總是更好更快?

  2. DBSet<T>有兩種口味WhereIQueryableIEnumerable)。有沒有辦法調用IEnumerable版本,因爲默認情況下會調用IQueryable,而不會調用ToList()

回答

7
  1. 如果IQueryable在服務器上而不是 獲取像IEnumerable所有記錄進行查詢表達式,爲什麼不IQueryable取代 通過IEnumerable它可以更快,更高效?

IQueryableIEnumerable代表兩個不同的事情。把IQueryable想象成一個「問題」,它本身沒有任何結果。一個IEnumerable是一個「答案」,它只有數據連接到它,但你不知道生成的數據是什麼。

這並不是說IQueryable每個說法都「更快」,它只是允許你將你的過濾和預測放到你問SQL服務器的「問題」中,讓它只返回它需要的答案(以IEnumerable的形式通過調用.ToList()或類似的形式)。

如果您只使用IEnumerable,那麼您可以問的唯一問題是「給我所有你知道的東西」,然後根據它給你的答案進行過濾和投影。這就是爲什麼IQueryable被認爲更快,因爲有更少的數據需要處理,因爲你可以向服務器提出更具體的問題。

原因IQueryable並沒有取代IEnumerable無處不在是因爲你問的問題必須能夠理解你問的問題。需要很多工作才能解析每個可能的事情,您可以通過它來過濾或投影大多數實現limit themselves to only common things they know they need to be able to answer。例如,在實體框架中,如果您提出的問題不明白如何處理,則會出現類似於的錯誤「指定的方法不受支持」當您嘗試從IQueryable獲得IEnumerable(答案)時。

  • DBSet<T>具有WhereIQueryableIEnumerable)兩種口味。 有沒有辦法調用IEnumerable版本,因爲默認情況下調用了 IQueryable,而不調用ToList()
  • DBSet<T>沒有Where method on it at all。兩個Where函數來自兩個擴展方法,Enumerable.WhereQueryable.Where。在調用擴展方法之前,可以強制它使用Enumerable超載,方法是將對象強制轉換爲IEnumerable<T>。不過請記住,Queryable.Where過濾問題,Enumerable.Where只過濾結果。

    從服務器請求結果然後把它們扔掉是浪費的,所以我不會推薦這樣做。

    +0

    你的例子(問題和答案)很好,正如我從它理解的那樣,'IQueryable'沒有用,直到我將它轉換爲IEnumerable列表才能得到理想的答案 –

    相關問題