linq中AsEnumerable和AsQueryable的區別

weixin_30588675發表於2020-04-05

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

轉載於:https://www.cnblogs.com/wangfuyou/p/6180557.html

相關文章