首先,,看定義: - public interface IQueryable : IEnumerable;
就是說(shuō),,IQueryable繼承于
IEnumerable。在此之上,,增加了一些屬性和擴(kuò)展方法,。但是,關(guān)鍵不在這些屬性和方法上,,而是 IQueryable實(shí)現(xiàn)了革命性的新行為方式,。 一般地,IQueryable用法如下: IQueryable<Customer> custs = from c in db.Customers
where c.City == "<City>" select c;
但是,,IQueryable<Customer> custs 不是一個(gè)實(shí)實(shí)在在的東西,,比如,常規(guī)的可以用 foreach操作的 一組對(duì)象,。
當(dāng)然,,有人會(huì)不同意,因?yàn)樗梢缘拇_可以使用 foreach 去操作一組對(duì)象,。 這有些矛盾,,這就是我為什么用“常規(guī)”這個(gè)詞。事實(shí)是,,當(dāng)你使用foreach之前,,這些對(duì)象并不存在。對(duì)于一組“常規(guī)”對(duì)象,,無(wú)論你“foreach”與否,,它們都已經(jīng)被生產(chǎn)并存在了。換句話說(shuō),,在 foreach 之前,,IQueryable<Customer> custs 并沒(méi)有在內(nèi)存中出現(xiàn),更精確地說(shuō),,沒(méi)有以數(shù)據(jù)的形式在內(nèi)存中出現(xiàn),。 這就是奇特的 IQueryable<T>.
它一種半數(shù)據(jù)半方法的東西。說(shuō)它是數(shù)據(jù),,因?yàn)榭梢韵駥?duì)象那樣操作它,;說(shuō)它是方法,因?yàn)樗?/font> 可以實(shí)現(xiàn)"延遲加載(lazy loading)行為,,即只有在使用時(shí)才生成對(duì)象和裝載數(shù)據(jù),。
為什么要發(fā)明和使用
IQueryable<T>,?
IEnumerable<T>不行嗎?
IQueryable<T>
關(guān)鍵的,,也是革命性的特性就是可以實(shí)現(xiàn)延遲加載,。有了
IQueryable<T>,就可以實(shí)現(xiàn)
LINQ to SQL,。它可以把一系列LINQ操作串聯(lián)起來(lái),,在最終數(shù)據(jù)集生成之前,沒(méi)有任何數(shù)據(jù)在內(nèi)存中產(chǎn)生,,這就大大降低了
LINQ操作對(duì)內(nèi)存的消耗,,而這種消耗實(shí)際上是巨大的。否則,,不得不用IEnumerable<T>,,它與 IQueryable<T>不同,它的所有操作都有在內(nèi)存中進(jìn)行,,即每步操作都要把數(shù)據(jù)從數(shù)據(jù)庫(kù)中加載到內(nèi)存中,。也許實(shí)現(xiàn)一個(gè)數(shù)據(jù)選擇操作,它耗費(fèi)了幾個(gè)M的內(nèi)存,,最后就用一個(gè)int,。
|