Daha önce çok şey söylendi, ancak daha teknik bir şekilde köklere dönelim:
IEnumerable
bellekte numaralandırabileceğiniz bir nesne topluluğudur - yinelemeyi mümkün kılan bir bellek içi dizilimdir ( yalnızca foreach
birlikte kullanabilmenize rağmen döngü içinde kolaylaştırır IEnumerator
). Hafızada olduğu gibi yaşıyorlar.
IQueryable
bir noktada , nihai sonuç üzerinde numaralandırma yeteneği olan başka bir şeye çevrilecek olan bir ifade ağacıdır . Sanırım çoğu insanın kafasını karıştıran şey bu.
Açıkçası farklı çağrışımları var.
IQueryable
LINQ toplama işlevleri (Sum, Count, vb.) veya ToList [Array, Dictionary, gibi yayın API'leri çağrıldığında temel sorgu sağlayıcı tarafından başka bir şeye çevrilecek bir ifade ağacını (sadece bir sorgu) temsil eder. ..]. Ve IQueryable
nesneler de uygular IEnumerable
, IEnumerable<T>
böylece bir sorguyu temsil ederlerse o sorgunun sonucu yinelenebilir. Bu, IQueryable'ın yalnızca sorgu olması gerekmediği anlamına gelir. Doğru terim ifade ağaçları olmasıdır .
Şimdi bu ifadelerin nasıl yürütüldüğünü ve neye dönüştüklerini, sorgu sağlayıcıları (bunları düşünebileceğimiz ifade yürütücüler) olarak adlandırıyoruz.
In Varlık Framework (yani mistik temel veri kaynağı sağlayıcı veya sorgu sağlayıcı olan) dünyaya IQueryable
ifadeleri yerli çevrilir T-SQL sorguları. Nhibernate
onlarla benzer şeyler yapıyor. Örneğin, LINQ'da oldukça iyi açıklanan kavramları izleyerek kendi kodunuzu yazabilirsiniz : Örneğin, bir IQueryable Sağlayıcısı bağlantısı oluşturma ve ürün deposu sağlayıcı hizmetiniz için özel bir sorgulama API'sına sahip olmak isteyebilirsiniz.
Temelde, IQueryable
nesneler, onları açıkça serbest bırakıp sisteme bunları SQL'e veya başka bir şekilde yeniden yazmasını ve yürütme zincirini ileriye doğru işlemek için göndermesini söyleyene kadar tamamen inşa ediliyor.
İçin Sanki ertelenmiş yürütme bir var LINQ
bellekte ifade ağacı şeması yukarı kaldırıp sadece sekans (aynı Kont, ToList, vs.) karşı denir her belirli API'leri talep üzerine icra içine göndermek için özellik.
Her ikisinin de doğru kullanımı, özel durum için karşılaştığınız görevlere bağlıdır. Şahsen geri dönmeyi tercih ettiğim iyi bilinen depo deseni için IList
, IEnumerable
Listeler (dizinleyiciler ve benzeri) üzerinde. Bu yüzden IQueryable
sadece depolarda ve kodda başka bir yerde IEnumerable içinde kullanmak benim tavsiyem . Ahlaksızlık ile ilgili endişelerin ayrılması ilkesini IQueryable
bozan ve bozan endişeler hakkında söylememek . Depolardan bir ifade döndürürseniz, tüketiciler istedikleri gibi kalıcılık katmanıyla oynayabilirler.
Dağınıklığa küçük bir ek :) (yorumlardaki bir tartışmadan)) Bunların hiçbiri, gerçek türler olmadıkları için bellekteki nesneler değildir, bir tür işaretleyicilerdir - eğer bu kadar derine gitmek istiyorsanız. Ancak IEnumerables'ı bellek içi koleksiyonlar olarak düşünürken, IQueryables'ı ifade ağaçları olarak düşünmek mantıklıdır (ve bu yüzden MSDN bile bu şekilde koydu). Buradaki nokta, IQueryable arabiriminin IEnumerable arabirimini devralır, böylece bir sorguyu temsil ederse, bu sorgunun sonuçları numaralandırılabilir. Numaralandırma, bir IQueryable nesnesiyle ilişkili ifade ağacının yürütülmesine neden olur. Yani, aslında, nesneyi hafızaya almadan IEnumerable üyelerini gerçekten çağıramazsınız. Eğer yaparsanız, zaten boş değilse, oraya girecektir. IQueryable'lar sadece sorgulardır, veriler değildir.