在寫LINQ語句的時候,往往會看到.AsEnumerable() 和 .AsQueryable() 。 例如: 1. string strcon = "Data Source=.\\SQLEXPRESS;Initial Catalog=Db_Example;Persist Security Info=True;User ID=sa;Password=sa"; SqlConnection con = new SqlConnection(strcon); con.Open(); string strsql = "select * from SC,Course where SC.Cno=Course.Cno"; SqlDataAdapter da = new SqlDataAdapter(strsql,con); DataSet ds = new DataSet(); da.Fill(ds, "mytable"); DataTable tables=ds.Tables["mytable"]; //創(chuàng)建表 var dslp = from d in tables.AsEnumerable() select d;//執(zhí)行LINQ語句,這里的.AsEnumerable()是延遲發(fā)生,不會立即執(zhí)行,實際上什么都沒有發(fā)生 foreach(var res in dslp) { Response.Write(res.Field<string>("Cname").ToString()); }
上述代碼使用LINQ 針對數(shù)據(jù)集中的數(shù)據(jù)進行篩選和整理,同樣能夠以一種面向對象的思想進行數(shù)據(jù)集中數(shù)據(jù)的篩選。在使用LINQ 進行數(shù)據(jù)集操作時,LINQ 不能直接從數(shù)據(jù)集對象中查詢,因為數(shù)據(jù)集對象不支持LINQ 查詢,所以需要使用AsEnumerable 方法返回一個泛型的對象以支持LINQ 的查詢操作。 .AsEnumerable()是延遲執(zhí)行的,實際上什么都沒有發(fā)生,當真正使用對象的時候(例如調用:First, Single, ToList....的時候)才執(zhí)行。 下面就是.AsEnumerable()與相對應的.AsQueryable()的區(qū)別: AsEnumerable將一個序列向上轉換為一個IEnumerable, 強制將Enumerable類下面的查詢操作符綁定到后續(xù)的子查詢當中。 AsQueryable將一個序列向下轉換為一個IQueryable, 它生成了一個本地查詢的IQueryable包裝。 - .AsEnumerable()延遲執(zhí)行,不會立即執(zhí)行。當你調用.AsEnumerable()的時候,實際上什么都沒有發(fā)生。
- .ToList()立即執(zhí)行
- 當你需要操作結果的時候,用.ToList(),否則,如果僅僅是用來查詢不需要進一步使用結果集,并可以延遲執(zhí)行,就用.AsEnumerable()/IEnumerable /IQueryable
- .AsEnumerable()雖然延遲執(zhí)行,但還是訪問數(shù)據(jù)庫,而.ToList()直接取得結果放在內存中。比如我們需要顯示兩個部門的員工時,部門可以先取出放置在List中,然后再依次取出各個部門的員工,這時訪問的效率要高一些,因為不需要每次都訪問數(shù)據(jù)庫去取出部門。
- IQueryable實現(xiàn)了IEnumberable接口。但IEnumerable<T> 換成IQueryable<T>后速度提高很多。原因:
- IQueryable接口與IEnumberable接口的區(qū)別: IEnumerable<T> 泛型類在調用自己的SKip 和 Take 等擴展方法之前數(shù)據(jù)就已經(jīng)加載在本地內存里了,而IQueryable<T> 是將Skip ,take 這些方法表達式翻譯成T-SQL語句之后再向SQL服務器發(fā)送命令,它并不是把所有數(shù)據(jù)都加載到內存里來才進行條件過濾。
- IEnumerable跑的是Linq to Object,強制從數(shù)據(jù)庫中讀取所有數(shù)據(jù)到內存先。
2、AsEnumerable和AsQueryable的實例 服務器端sql 服務器端sql
|