1、C#中LINQ to Objects中延遲查詢的陷阱(其他類型的LINQ也基本一致) 之前在不瞭解LINQ延遲查詢的時候,我使用下麵的這種方式,將where語句的結果直接as為List<T>對象,結果得到的temp為NULL,苦思不得其解; 求解思路: 一開始以為是LINQ語句的問題,但是在反覆 ...
1、C#中LINQ to Objects中延遲查詢的陷阱(其他類型的LINQ也基本一致)
之前在不瞭解LINQ延遲查詢的時候,我使用下麵的這種方式,將where語句的結果直接as為List<T>對象,結果得到的temp為NULL,苦思不得其解;
List<person> lst = new List<person>(){ new person(){id=1,name="cyong"}, new person(){id=2,name="lshan"} }; List<person> temp = lst.Where(m => m.id > 1) as List<person>;
求解思路:
一開始以為是LINQ語句的問題,但是在反覆測試之後,發現 lst.Where(m => m.id > 1) 確實是語法正確的,並且能夠在調用ToList()擴展方法後返回正確的結果集;
而後,考慮是as的問題,查看as的使用方式,發現as是類型安全的轉換方式,當轉換失敗時不會報錯,而是返回null;但是查看文檔發現Where語句返回的是IEnumerable<TSource>,而IEnumerable<T>在一般情況下(比如我先將一個List<T>轉換為IEnumerable<T>,再通過一次as轉換回來)是可以正常轉換為List<T>的;
求助:
然後就將這個問題拋給了群裡面的一群大神。經過一番指點,才發現這個問題的緣由是LINQ的懶載入(延遲查詢)。
上文檔:
文檔中介紹到【查詢變數本身只存儲查詢命令。查詢的實際執行將推遲到“foreach”語句中迴圈訪問查詢變數之後進行;同時,也可以通過ToList或者ToArray方法強制立即執行,以將查詢結果緩存到單個集合對象中】
Enumerable.Where<TSource>方法(IEnumerable<TSource>,Func<TSource,Int32,Boolean>)
此方法使用的是LINQ的延遲查詢。
結論:
1、LINQ查詢只是緩存查詢命令,要訪問查詢結果,應該使用foreach去迭代或者使用ToList()或者ToArray方法強制立即執行並緩存到集合對象中。
2、MSDN文檔不得不看看。
附圖:
1、同行指教