一个简单问题引发对IEnumerable和IQueryable的思考
問題概述:
?? 首先看下圖,有客戶表和客戶負責人表關系是多對多,訪問數據庫使用的是EF所以這里我們開啟了延遲加載,需求就是將每個客戶的所有負責人逗號拼接顯示在負責人這一欄位,
???????? 對你沒看錯需求就是這么簡單如果是寫sql也許我們會去用兩個循環去做,問題是要用linq實現。
?
?
這是我起初的寫法:
首先申明這個resultlist接收到的類型本該是Iqueryable<Customer> 但我們要放入PrincipalNames字段(逗號拼接顯示字段)所以接收的是匿名類型 這樣寫報的錯是:
大概意思:LINQ實體不能識別方法的系統。字符串連接(系統。system . String[])字符串,的方法,這種方法不能被翻譯成一個存儲表達式
然后各種百度谷歌發現其原因是將這段linq翻譯成sql的時候string.Join()方法不被識別也就是沒法翻譯,這時我就郁悶了,甚至懷疑linq
能不能實現這樣的需求、
中途有想過不用linq實現,用兩個循環賦值去實現實現:做法就是先循環客戶信息再循環客戶下的負責人將負責人的名稱拼接賦值給客戶的負責人
但由于前面客戶是匿名類型PrincipalNames并不存在客戶表中所以不能賦值,so解決方案就是還要在建立一個含有PrincipalNames字段的視圖模型
這樣才能循環后去賦值!我也是醉了,咋這麻煩。
又想了想不可能啊 這樣的需求很正常不是嗎linq怎么可能不能實現,繼續找~
在博客園找都一篇闡述IEnumerable和IQueryable區別的文章:http://www.cnblogs.com/FlyEdward/archive/2010/02/01/Linq_ExpressionTree2.html
感覺有點意思繼續找類似的文章佐證,發現還真是這東西在作怪 ,先看看正確的查詢寫法:
重點就在我劃紅線的地方這樣寫resultlist接收的類型是IEnumberable<Customer>類型這樣寫其會先將數據全部查入內存中在進行查詢,并沒有將
后面的條件也就是匿名類里面的東西包括string.Join方法翻譯成sql 這樣就不會出現之前不能string.Join()方法不識別的問題了,OK解決!
總結:
IQueryable繼承自IEnumerable,所以對于數據遍歷來說,它們沒有區別。
1.IEnumerable查詢必須在本地執行.并且執行查詢前我們必須把所有的數據加載到本地.而且更多的時候.加載的數據有大量的數據是我們不需要的無效數據.但是我們卻不得不傳輸更多的數據.做更多的無用功。
使用IEnumerable,所有對于IEnumerable的過濾,排序等操作,都是在內存中發生的。也就是說數據已經從數據庫中獲取到了內存中,只是在內存中進行過濾和排序操作。
2.IQueryable卻總能只提供你所需要的數 據.大大減少了數據的傳輸
IQueryable的優勢是它有表達式樹,所有對于IQueryable的過濾,排序等操作,都會先緩存到表達式樹中,只有當真正遍歷發生的時候,才會將表達式樹由IQueryProvider執行獲取數據操作。
以上觀點屬個人領悟,若有問題歡迎糾正。
?
轉載于:https://www.cnblogs.com/fighting2014/p/4239723.html
總結
以上是生活随笔為你收集整理的一个简单问题引发对IEnumerable和IQueryable的思考的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jQuery常用的选择器
- 下一篇: 10天学安卓-第六天