1.簡介
用Linq來操作集合的時候會用到AsQueryable()和AsEnumerable(),何時該用AsQueryable()和何時該用AsEnumerable(),或許存在些疑惑。AsQueryable是在資料庫中查詢再返回資料,AsEnumerable是從資料庫讀取全部資料再在程式中查詢。
在使用LINQ 進行資料集操作時,LINQ 不能直接從資料集物件中查詢,因為資料集物件不支援LINQ 查詢,所以需要使用AsEnumerable 方法返回一個泛型的物件以支援LINQ 的查詢操作。
例如
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"]; //建立表
var dslp = from d in tables.AsEnumerable() select d;//執行LINQ語句,這裡的.AsEnumerable()是延遲發生,不會立即執行,實際上什麼都沒有發生
foreach(var res in dslp)
{
Response.Write(res.Field<string>("Cname").ToString());
}
一、linq中AsEnumerable和AsQueryable的區別
1、AsEnumerable()是延遲執行的,實際上什麼都沒有發生,當真正使用物件的時候(例如呼叫:First, Single, ToList....的時候)才執行。
2、AsEnumerable將一個序列向上轉換為一個IEnumerable, 強制將Enumerable類下面的查詢操作符繫結到後續的子查詢當中。
3、AsQueryable將一個序列向下轉換為一個IQueryable, 它生成了一個本地查詢的IQueryable包裝。
4、AsEnumerable()延遲執行,不會立即執行。當你呼叫.AsEnumerable()的時候,實際上什麼都沒有發生。
5、ToList()立即執行
6、當你需要操作結果的時候,用.ToList(),否則,如果僅僅是用來查詢不需要進一步使用結果集,並可以延遲執行,就用.AsEnumerable()/IEnumerable /IQueryable
7、AsEnumerable()雖然延遲執行,但還是訪問資料庫,而.ToList()直接取得結果放在記憶體中。比如我們需要顯示兩個部門的員工時,部門可以先取出放置在List中,然後再依次取出各個部門的員工,這時訪問的效率要高一些,因為不需要每次都訪問資料庫去取出部門。
8、IQueryable實現了IEnumberable介面。但IEnumerable<T> 換成IQueryable<T>後速度提高很多。
9、IQueryable介面與IEnumberable介面的區別: IEnumerable<T> 泛型類在呼叫自己的SKip 和 Take 等擴充套件方法之前資料就已經載入在本地記憶體裡了,而IQueryable<T> 是將Skip ,take 這些方法表示式翻譯成T-SQL語句之後再向SQL伺服器傳送命令,它並不是把所有資料都載入到記憶體裡來才進行條件過濾。
10、IEnumerable跑的是Linq to Object,強制從資料庫中讀取所有資料到記憶體先。
二、AsEnumerable和AsQueryable的例項
using (testContext context = new testContext())
{
var query = (from item in context.Users.AsQueryable()
where item.id > 10
select item.id).ToList();
var query2 = (from item in context.Users.AsEnumerable()
where item.id > 10
select item.id).ToList();
}
伺服器端sql
--AsQueryable Select [Extent1].[id] AS [id] FROM [dbo].[User] AS [Extent1] Where [Extent1].[id] > 10 --AsEnumerable Select [Extent1].[id] AS [id], [Extent1].[usn] AS [usn], [Extent1].[pwd] AS [pwd], [Extent1].[created] AS [created] FROM [dbo].[User] AS [Extent1]
例項二
using (testContext context = new testContext()) { var query = (from item in context.Users.AsQueryable() where item.id > 10 orderby item.id ascending select item.id).Skip(20).Take(20).ToList(); var query2 = (from item in context.Users.AsEnumerable() where item.id > 10 orderby item.id ascending select item.id).Skip(20).Take(20).ToList(); }
伺服器端sql
--AsQueryable Select TOP (20) [Filter1].[id] AS [id] FROM ( Select [Extent1].[id] AS [id], row_number() OVER (ORDER BY [Extent1].[id] ASC) AS [row_number] FROM [dbo].[User] AS [Extent1] Where [Extent1].[id] > 10 ) AS [Filter1] Where [Filter1].[row_number] > 20 orDER BY [Filter1].[id] ASC --AsEnumerable Select [Extent1].[id] AS [id], [Extent1].[usn] AS [usn], [Extent1].[pwd] AS [pwd], [Extent1].[created] AS [created] FROM [dbo].[User] AS [Extent1]
轉:http://www.studyofnet.com/news/682.html