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 foreachbirlikte 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.
IQueryableLINQ 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 IQueryablenesneler 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 IQueryableifadeleri yerli çevrilir T-SQL sorguları. Nhibernateonlarla 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, IQueryablenesneler, 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 LINQbellekte 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, IEnumerableListeler (dizinleyiciler ve benzeri) üzerinde. Bu yüzden IQueryablesadece depolarda ve kodda başka bir yerde IEnumerable içinde kullanmak benim tavsiyem . Ahlaksızlık ile ilgili endişelerin ayrılması ilkesini IQueryablebozan 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.