Banyak yang telah dikatakan sebelumnya, tetapi kembali ke akarnya, dengan cara yang lebih teknis:
IEnumerable adalah kumpulan objek dalam memori yang dapat Anda hitung - urutan dalam memori yang memungkinkan untuk foreachdiulang (membuatnya mudah untuk dilakukan dalam loop, meskipun Anda hanya dapat menggunakannya IEnumerator). Mereka tinggal di memori apa adanya.
IQueryable adalah pohon ekspresi yang akan diterjemahkan ke sesuatu yang lain di beberapa titik dengan kemampuan untuk menghitung hasil akhir . Saya kira inilah yang membingungkan kebanyakan orang.
Mereka jelas memiliki konotasi yang berbeda.
IQueryablemewakili pohon ekspresi (permintaan, sederhana) yang akan diterjemahkan ke sesuatu yang lain oleh penyedia permintaan yang mendasari segera setelah rilis API disebut, seperti fungsi agregat LINQ (Jumlah, Hitungan, dll.) atau Daftar [Array, Kamus,. ..] Dan IQueryableobjek juga diimplementasikan IEnumerable, IEnumerable<T>sehingga jika mereka merepresentasikan kueri , hasil dari kueri itu bisa diulang. Itu berarti IQueryable tidak harus menjadi pertanyaan saja. Istilah yang tepat adalah mereka pohon ekspresi .
Sekarang bagaimana ekspresi itu dieksekusi dan apa yang mereka berubah adalah semua yang disebut penyedia kueri (eksekutor ekspresi kita dapat memikirkannya).
Di dunia Entity Framework (yaitu penyedia sumber data yang mendasari mistis, atau penyedia kueri) IQueryablediterjemahkan ke dalam kueri T-SQL asli . Nhibernatemelakukan hal serupa dengan mereka. Anda dapat menulis sendiri mengikuti konsep yang dijelaskan dengan baik di LINQ: Membangun tautan Penyedia IQueryable , misalnya, dan Anda mungkin ingin memiliki API kueri khusus untuk layanan penyedia toko produk Anda.
Jadi pada dasarnya, IQueryableobjek sedang dibangun jauh sampai kita secara eksplisit melepaskannya dan memberitahu sistem untuk menulis ulang mereka ke dalam SQL atau apa pun dan mengirimkan rantai eksekusi untuk diproses selanjutnya.
Seolah-olah untuk menunda eksekusi, ini adalah LINQfitur untuk menahan skema pohon ekspresi di memori dan mengirimkannya ke eksekusi hanya berdasarkan permintaan, setiap kali API tertentu dipanggil terhadap urutan (Hitungan yang sama, Daftar, dll.).
Penggunaan keduanya sangat tergantung pada tugas yang Anda hadapi untuk kasus tertentu. Untuk pola repositori terkenal saya pribadi memilih untuk kembali IList, yaitu IEnumerablelebih dari Daftar (pengindeks dan sejenisnya). Jadi ini adalah saran saya untuk menggunakan IQueryablehanya di dalam repositori dan IEnumerable di tempat lain dalam kode. Tidak mengatakan tentang kekhawatiran yang dapat diuji yang IQueryablerusak dan merusak prinsip pemisahan kekhawatiran . Jika Anda mengembalikan ekspresi dari dalam repositori, konsumen dapat bermain dengan lapisan kegigihan seperti yang mereka inginkan.
Sedikit tambahan ke kekacauan :) (dari diskusi di komentar)) Tidak satu pun dari mereka adalah objek dalam memori karena mereka bukan tipe nyata per se, mereka adalah penanda jenis - jika Anda ingin pergi sedalam itu. Tetapi masuk akal (dan itulah sebabnya bahkan MSDN mengatakannya seperti ini) untuk memikirkan IEnumerables sebagai koleksi dalam memori sedangkan IQueryables sebagai pohon ekspresi. Intinya adalah bahwa antarmuka IQueryable mewarisi antarmuka IEnumerable sehingga jika itu merupakan permintaan, hasil dari permintaan itu dapat disebutkan. Pencacahan menyebabkan pohon ekspresi yang terkait dengan objek IQueryable dieksekusi. Jadi, sebenarnya, Anda tidak dapat benar-benar memanggil anggota IEnumerable tanpa memiliki objek di memori. Ini akan masuk ke sana jika Anda melakukannya, jika tidak kosong. IQueryables hanyalah pertanyaan, bukan data.