'fark(s) arasında ne .() ToList, .() AsEnumerable, AsQueryable()?
İlk uygular ve ikinci uygular IQueryable ve IEnumerable hangi L2E L2O bazı diefferences biliyorum ve Q benim kapsamı EF 5 içinde.
Benim Q teknik farkı(ler) Bu 3 yöntemleri. Birçok durumda hepsi çalışıyormuşsunuz. Ben de onlara kombinasyonları kullanarak .ToList().AsQueryable()
gibi görüyor.
1) Bu yöntem tam olarak ne demek?
2) başkaları ile karşılaştırıldığında, onlar hakkında herhangi bir performans ya da başka bir sorunu var mı?
Neden 3) örneğin .AsQueryable()
yerine .ToList().AsQueryable()
?
Şimdiden teşekkürler
CEVAP
Bu konuda söylenecek çok şey var. Beni AsEnumerable
AsQueryable
odaklanalım ve yol boyunca ToList()
söz.
Bu yöntemler ne yaparsınız?
AsEnumerable
AsQueryable
IEnumerable
dökme dönüştürmek veya 23**, sırasıyla. Derimcast veya convertbir nedeni:
Kaynak Hedef arabirimini uygulayan nesne, kaynak ama döndürülen nesnesidökmehedef arabirimi. Diğer bir deyişle: türü değişmez, ancak derleme zamanı türüdür.
Kaynak nesneyi hedef arabirim uygulamıyor, kaynak nesnedönüştürülmüşhedef arabirimi uygulayan bir nesne haline. Her iki türü ve derleme türü değişti.
Bana bir örnek ile bunu gösterelim. Derleme zamanı tür ve (courtesy Jon Skeet) bir nesnenin gerçek türü raporlar küçük bir yöntem var:
void ReportTypeProperties<T>(T obj)
{
Console.WriteLine("Compile-time type: {0}", typeof(T).Name);
Console.WriteLine("Actual type: {0}", obj.GetType().Name);
}
Hadi rasgele bir seri-to-sql IQueryable
uygulayan Table<T>
, deneyin:
ReportTypeProperties(context.Observations);
ReportTypeProperties(context.Observations.AsEnumerable());
ReportTypeProperties(context.Observations.AsQueryable());
Sonuç:
Compile-time type: Table`1
Actual type: Table`1
Compile-time type: IEnumerable`1
Actual type: Table`1
Compile-time type: IQueryable`1
Actual type: Table`1
Sınıfın hep döndü kendisi olduğunu görürsünüz, ama onun temsil değiştirir.
Şimdi IEnumerable
, IQueryable
uygulayan bir nesne:
var ints = new[] { 1, 2 };
ReportTypeProperties(ints);
ReportTypeProperties(ints.AsEnumerable());
ReportTypeProperties(ints.AsQueryable());
Sonuçları:
Compile-time type: Int32[]
Actual type: Int32[]
Compile-time type: IEnumerable`1
Actual type: Int32[]
Compile-time type: IQueryable`1
Actual type: EnumerableQuery`1
İşte orada. AsQueryable()
bir dizi "IQueryable<T>
veri kaynağı olarak IEnumerable<T>
bir topluluğu temsil eder." EnumerableQuery
, dönüştürdü (MSDN).
Ne işe yarar?
AsEnumerable
çoğunlukla eski L2O olan fonksiyonları desteklemiyor çünkü nesneleri (L2O) bu SERİ için IQueryable
herhangi bir uygulamadan geçiş yapmak için kullanılır. Daha fazla bilgi için bkz: What is the effect of AsEnumerable() on a LINQ Entity?.
Varlık Çerçevesi sorgusu örneğin, yalnızca yöntemlerinin sınırlı sayıda kullanabiliriz. Eğer öyleyse, örneğin, genellikle gibi bir şey yazmak istiyoruz sorguda kendi yöntemleri kullanmamız gerekiyor
var query = context.Observations.Select(o => o.Id)
.AsEnumerable().Select(x => MySuperSmartMethod(x))
ToList
IEnumerable<T>
List<T>
– genellikle bu amaç için kullanılır. bir dönüştüren – ToList
vs AsEnumerable
kullanmanın avantajı AsEnumerable
sorgu yürütmek değil. AsEnumerable
ertelenmiş yürütme korur ve genellikle işe yaramaz Ara bir liste oluşturmak değil.
SERİ bir sorgu zorla çalıştırma istenilen diğer taraftan,, ToList
bunu yapmak için bir yol olabilir.
AsQueryable
sayısız bir koleksiyon yapmak için kullanılabilir ETMENİZ ifadeleri ifadeleri kabul edin. Daha fazla bilgi için buraya bakınız: Do i really need use AsQueryable() on collection?.
Madde kullanımı ile ilgili not!
AsEnumerable
bir ilaç gibi çalışır. Hızlı bir düzeltme, ama hiç bir maliyet ve altta yatan sorunu çözmek değil.
Taşma cevaplar Yığını, insanlar AsEnumerable
SERİ ifadelerde desteklenmeyen bir yöntem ile herhangi bir sorunu çözmek için uygulama görüyorum. Ama fiyat her zaman açık değildir. Eğer bunu yaparsanız, örneğin, bu:
context.MyLongWideTable // A table with many records and columns
.Where(x => x.Type == "type")
.Select(x => new { x.Name, x.CreateDate })
...her şey düzenli bir şekilde SQL deyimi çevrilirfiltreler(Where
)projeler(Select
). Diğer bir deyişle, SQL sonuç kümesi uzunluğu ve genişliği her ikisi de, sırasıyla, azalır.
Artık kullanıcılar sadece tarih CreateDate
parçası görmek istediğinizi varsayalım. Varlık Çerçevesi içinde hızlı bir şekilde keşfedeceksiniz...
.Select(x => new { x.Name, x.CreateDate.Date })
...desteklenen (yazma anda). Ah, neyse ki AsEnumerable
düzeltme var:
context.MyLongWideTable.AsEnumerable()
.Where(x => x.Type == "type")
.Select(x => new { x.Name, x.CreateDate.Date })
Tabii, muhtemelen çalışır. Ama belleğe tüm masa çeker ve daha sonra filtre ve tahminler geçerlidir. Çoğu insan Where
ilk yapmak için yeterince akıllı
context.MyLongWideTable
.Where(x => x.Type == "type").AsEnumerable()
.Select(x => new { x.Name, x.CreateDate.Date })
Ama yine de tüm sütunları ilk getirilen ve projeksiyon bellekte yapılır.
Gerçek düzeltme:
context.MyLongWideTable
.Where(x => x.Type == "type")
.Select(x => new { x.Name, DbFunctions.TruncateTime(x.CreateDate) })
(Ama bu biraz daha fazla bilgi gerektirir...)
Bu yöntemler ne?
Şimdi önemli bir uyarı. Ne zaman
context.Observations.AsEnumerable()
.AsQueryable()
kaynak IQueryable
olarak temsil edilen nesne ile sona erecek. Her iki yöntem de sadece cast ve convert yok çünkü).
Ama ne zaman
context.Observations.AsEnumerable().Select(x => x)
.AsQueryable()
sonuç ne olur?
Select
WhereSelectEnumerableIterator
üretir. Bu bir iç .Net sınıf IEnumerable
uygular67 ** değil. Başka tür bir dönüşüm gerçekleşmiş ve AsQueryable
sonraki asıl kaynağı artık dönebilirsiniz.
Bu ima AsQueryable
kullanaraksihirli bir şekilde değil enjekte sorgu sağlayıcısıbir sayısız içine kendine has özellikleri ile. Sanırım öyle
var query = context.Observations.Select(o => o.Id)
.AsEnumerable().Select(x => x.ToString())
.AsQueryable()
.Where(...)
Burada durum hiç SQL tercüme edilecektir. AsEnumerable()
SERİ açıklamaları ardından kesin olarak varlık çerçevesi sorgu kuruluşu ile bağlantıyı keser.
Ben mesela kişi '' AsQueryable
çağırarak. bir koleksiyon Include
yetenekler kazandırmak için çabaladığımız burada soruları gördüm çünkü kasıtlı olarak bu örnek göster Derler ve çalıştırır, ama temel nesne Include
uygulaması artık yok, çünkü hiçbir şey yapmaz.
Belirli Uygulamaları
Şimdiye kadar, bu sadece Queryable.AsQueryable
ve Enumerable.AsEnumerable
uzatma yöntemleri hakkında. Ama tabii ki herkes aynı adı taşıyan örnek yöntemleri veya uzatma yöntemleri (fonksiyonlar) yazabilirsiniz.
Aslında AsEnumerable
uzantısı belirli bir yöntemin yaygın bir örnek DataTableExtensions.AsEnumerable
. DataTable
düzenli uzatma yöntemleri uygulamak yok IQueryable
veya* *81, uygulamıyor.
@Arasında daha Önce fark @BeforeClass...
Fark arasında bahar @Denetleyicisi ve ...
İşte yeni Görüntü arasında fark var mı...
Bu özel durumda, bir kurucu üye başlat...
Chrome dev tools Ağ sekmesinde görüldü...