Apa perbedaan antara IQueryable<T>dan IEnumerable<T>?
Lihat juga Apa perbedaan antara IQueryable dan IEnumerable yang tumpang tindih dengan pertanyaan ini.
Apa perbedaan antara IQueryable<T>dan IEnumerable<T>?
Lihat juga Apa perbedaan antara IQueryable dan IEnumerable yang tumpang tindih dengan pertanyaan ini.
Jawaban:
Pertama-tama, meluas yang antarmuka, sehingga apa pun yang Anda bisa lakukan dengan "polos" , Anda juga dapat melakukan dengan .IQueryable<T> IEnumerable<T>IEnumerable<T>IQueryable<T>
IEnumerable<T>hanya memiliki GetEnumerator()metode yang mengembalikan sebuah Enumerator<T>yang Anda dapat menghubungi yang MoveNext()metode untuk iterate melalui urutan T .
Apa IQueryable<T>yang IEnumerable<T> tidak memiliki itu adalah dua properti khususnya — yang menunjuk ke penyedia kueri (mis., Penyedia LINQ ke SQL) dan yang lain menunjuk ke ekspresi kueri yang mewakili IQueryable<T>objek sebagai pohon sintaks abstrak runtime-traversable yang bisa menjadi dipahami oleh penyedia kueri yang diberikan (sebagian besar, Anda tidak bisa memberikan ekspresi LINQ ke SQL ke penyedia LINQ ke Entitas tanpa pengecualian dilemparkan).
Ekspresi dapat berupa ekspresi konstan dari objek itu sendiri atau pohon yang lebih kompleks dari kumpulan operator dan operan kueri yang terdiri. Penyedia IQueryProvider.Execute()atau IQueryProvider.CreateQuery()metode kueri dipanggil dengan Ekspresi yang diteruskan ke sana, dan kemudian salah satu hasil kueri atau lainnya IQueryabledikembalikan, masing-masing.
AsQueryable()hanya akan melemparkan enumerable ke queryable dan mengembalikannya jika itu mengimplementasikan IQueryableantarmuka, jika tidak membungkusnya dalam ConstantExpression, yang disebut dalam EnumerableQueryobjek yang dikembalikan .
Perbedaan utama adalah bahwa operator LINQ untuk IQueryable<T>mengambil Expressionobjek alih-alih delegasi, yang berarti logika kueri kustom yang diterimanya, misalnya, predikat atau pemilih nilai, adalah dalam bentuk pohon ekspresi daripada delegasi ke metode.
IEnumerable<T> bagus untuk bekerja dengan urutan yang di-memori berulang, tetapi IQueryable<T> memungkinkan kehabisan memori hal-hal seperti sumber data jarak jauh, seperti database atau layanan web.Di mana eksekusi permintaan akan dilakukan "dalam proses" , biasanya semua yang diperlukan adalah kode (sebagai kode) untuk mengeksekusi setiap bagian dari permintaan.
Di mana eksekusi akan dilakukan di luar proses , logika kueri harus diwakili dalam data sehingga penyedia LINQ dapat mengubahnya menjadi bentuk yang sesuai untuk eksekusi di luar memori - apakah itu permintaan LDAP, SQL atau apa pun.
Lebih banyak di:
IEnumerable<T>danIQueryable<T>IEnumerable<T>vsIQueryable<T> "IEnumerable, IQueryable, IObservable, danIQbservable
Ini adalah video yang bagus di youtube yang menunjukkan bagaimana antarmuka ini berbeda, layak tonton.
Di bawah ini pergi jawaban deskriptif panjang untuk itu.
Poin penting pertama yang harus diingat adalah IQueryableantarmuka diturunkan IEnumerable, jadi apa pun yang IEnumerablebisa dilakukan, IQueryablejuga bisa dilakukan.

Ada banyak perbedaan tetapi mari kita bahas tentang satu perbedaan besar yang membuat perbedaan terbesar. IEnumerableantarmuka berguna ketika koleksi Anda dimuat menggunakan LINQatau kerangka kerja Entity dan Anda ingin menerapkan filter pada koleksi.
Pertimbangkan kode sederhana di bawah ini yang digunakan IEnumerabledengan kerangka kerja entitas. Ini menggunakan Wherefilter untuk mendapatkan catatan yang EmpIdadalah 2.
EmpEntities ent = new EmpEntities();
IEnumerable<Employee> emp = ent.Employees;
IEnumerable<Employee> temp = emp.Where(x => x.Empid == 2).ToList<Employee>();
Filter ini dijalankan di sisi klien tempat IEnumerablekode berada. Dengan kata lain semua data diambil dari database dan kemudian pada klien scan dan mendapat catatan dengan EmpIditu 2.

Tapi sekarang lihat di bawah kode yang kami telah berubah IEnumerableke IQueryable. Itu menciptakan SQL Query di sisi server dan hanya data yang diperlukan dikirim ke sisi klien.
EmpEntities ent = new EmpEntities();
IQueryable<Employee> emp = ent.Employees;
IQueryable<Employee> temp = emp.Where(x => x.Empid == 2).ToList<Employee>();

Jadi perbedaan antara IQueryabledan IEnumerabletentang di mana filter logika dijalankan. Satu dieksekusi di sisi klien dan yang lain dijalankan pada database.
Jadi jika Anda hanya bekerja dengan pengumpulan data dalam memori IEnumerableadalah pilihan yang baik tetapi jika Anda ingin meminta pengumpulan data yang terhubung dengan database `IQueryable adalah pilihan yang lebih baik karena mengurangi lalu lintas jaringan dan menggunakan kekuatan bahasa SQL.
IEnumerable: IEnumerable paling cocok untuk bekerja dengan koleksi di-memori (atau permintaan lokal). IEnumerable tidak bergerak di antara item, itu hanya koleksi ke depan.
IQueryable: IQueryable paling cocok untuk sumber data jarak jauh, seperti basis data atau layanan web (atau permintaan jarak jauh). IQueryable adalah fitur yang sangat kuat yang memungkinkan berbagai skenario eksekusi yang ditangguhkan menarik (seperti permintaan halaman dan komposisi berdasarkan).
Jadi ketika Anda harus hanya mengulangi melalui koleksi di dalam memori, gunakan IEnumerable, jika Anda perlu melakukan manipulasi dengan koleksi seperti Dataset dan sumber data lainnya, gunakan IQueryable
Dalam kehidupan nyata, jika Anda menggunakan ORM seperti LINQ-to-SQL
Dalam kedua kasus jika Anda tidak memanggil ToList()atau ToArray()kemudian permintaan akan dieksekusi setiap kali digunakan, jadi, katakanlah, Anda memiliki IQueryable<T>dan Anda mengisi 4 kotak daftar dari itu, maka permintaan akan dijalankan terhadap database 4 kali.
Juga jika Anda memperluas kueri Anda:
q.Where(x.name = "a").ToList()
Kemudian dengan IQueryable SQL yang dihasilkan akan berisi "di mana nama =" a ", tetapi dengan IEnumerable banyak peran akan ditarik kembali dari database, maka pemeriksaan x.name =" a "akan dilakukan oleh .NET.
Tes kecil yang disebutkan di bawah ini dapat membantu Anda memahami satu aspek perbedaan antara IQueryable<T>dan IEnumerable<T>. Saya telah mereproduksi jawaban ini dari pos ini di mana saya mencoba menambahkan koreksi ke pos orang lain
Saya membuat struktur berikut dalam DB (skrip DDL):
CREATE TABLE [dbo].[Employee]([PersonId] [int] NOT NULL PRIMARY KEY,[Salary] [int] NOT NULL)
Berikut ini skrip penyisipan rekaman (skrip DML):
INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(1, 20)
INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(2, 30)
INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(3, 40)
INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(4, 50)
INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(5, 60)
GO
Sekarang, tujuan saya adalah hanya mendapatkan 2 catatan teratas dari Employeetabel dalam database. Saya menambahkan item Model Data Entitas ADO.NET ke dalam aplikasi konsol saya yang menunjuk ke Employeetabel dalam database saya dan mulai menulis kueri LINQ.
Kode untuk rute IQueryable :
using (var efContext = new EfTestEntities())
{
IQueryable<int> employees = from e in efContext.Employees select e.Salary;
employees = employees.Take(2);
foreach (var item in employees)
{
Console.WriteLine(item);
}
}
Ketika saya mulai menjalankan program ini, saya juga memulai sesi profiler SQL Query pada contoh SQL Server saya dan di sini adalah ringkasan dari eksekusi:
SELECT TOP (2) [c].[Salary] AS [Salary] FROM [dbo].[Employee] AS [c]Hanya itu saja IQueryable cukup pintar untuk menerapkan Top (2)klausa di sisi server database itu sendiri sehingga hanya membawa 2 dari 5 catatan melalui kabel. Penyaringan dalam memori lebih lanjut tidak diperlukan sama sekali di sisi komputer klien.
Kode untuk rute IEnumerable :
using (var efContext = new EfTestEntities())
{
IEnumerable<int> employees = from e in efContext.Employees select e.Salary;
employees = employees.Take(2);
foreach (var item in employees)
{
Console.WriteLine(item);
}
}
Ringkasan eksekusi dalam hal ini:
SELECT [Extent1].[Salary] AS [Salary]
FROM [dbo].[Employee] AS [Extent1]Sekarang masalahnya IEnumerabledibawa semua 5 catatan hadir dalam Salarytabel dan kemudian melakukan pemfilteran di-memori pada komputer klien untuk mendapatkan 2 catatan teratas. Jadi lebih banyak data (3 catatan tambahan dalam kasus ini) yang ditransfer melalui kabel tanpa perlu.
Inilah yang saya tulis pada posting serupa (pada topik ini). (Dan tidak, saya biasanya tidak mengutip diri saya sendiri, tetapi ini adalah artikel yang sangat bagus.)
"Artikel ini bermanfaat: IQueryable vs IEnumerable di LINQ-to-SQL .
Mengutip artikel itu, 'Sesuai dokumentasi MSDN, panggilan yang dibuat di IQueryable beroperasi dengan membangun pohon ekspresi internal sebagai gantinya. "Metode-metode ini yang memperluas IQueryable (Of T) tidak melakukan kueri langsung. Alih-alih, fungsinya adalah untuk membangun objek Ekspresi, yang merupakan pohon ekspresi yang mewakili permintaan kumulatif." '
Pohon ekspresi adalah konstruk yang sangat penting dalam C # dan pada platform .NET. (Mereka penting secara umum, tetapi C # membuatnya sangat berguna.) Untuk lebih memahami perbedaannya, saya sarankan membaca tentang perbedaan antara ekspresi dan pernyataan dalam spesifikasi resmi C # 5.0 di sini. Untuk konsep teoritis canggih yang bercabang ke dalam kalkulus lambda, ekspresi memungkinkan dukungan untuk metode sebagai objek kelas satu. Perbedaan antara IQueryable dan IEnumerable berpusat di sekitar titik ini. IQueryable membangun pohon ekspresi sedangkan IEnumerable tidak, setidaknya tidak secara umum untuk kita yang tidak bekerja di laboratorium rahasia Microsoft.
Berikut ini adalah artikel lain yang sangat berguna yang merinci perbedaan dari perspektif push vs pull. (Dengan "push" vs. "pull," saya mengacu pada arah aliran data. Teknik Pemrograman Reaktif untuk .NET dan C #
Berikut ini adalah artikel yang sangat bagus yang merinci perbedaan antara pernyataan lambdas dan ekspresi lambdas dan membahas konsep ekspresi tress secara lebih mendalam: Meninjau kembali delegasi C #, pohon ekspresi, dan pernyataan lambda vs ekspresi lambda. . "
Kami menggunakan IEnumerabledan IQueryableuntuk memanipulasi data yang diambil dari basis data. IQueryablemewarisi dari IEnumerable, demikian IQueryablejuga mengandung semua IEnumerablefitur. Perbedaan utama antara IQueryabledan IEnumerableadalah yang IQueryablemengeksekusi kueri dengan filter sedangkan IEnumerablemengeksekusi kueri pertama dan kemudian menyaring data berdasarkan kondisi.
Temukan diferensiasi lebih rinci di bawah ini:
Tidak terhitung
IEnumerableada di System.CollectionsnamespaceIEnumerable menjalankan kueri pemilihan di sisi server, memuat data dalam memori pada sisi klien dan kemudian menyaring dataIEnumerable cocok untuk menanyakan data dari koleksi dalam memori seperti Daftar, ArrayIEnumerable bermanfaat untuk LINQ to Object dan LINQ to query XMLIQueryable
IQueryableada di System.LinqnamespaceIQueryable mengeksekusi 'query pilih' di sisi server dengan semua filterIQueryable cocok untuk menanyakan data dari koleksi out-memory (seperti basis data jauh, layanan)IQueryable bermanfaat untuk permintaan LINQ to SQLJadi IEnumerableumumnya digunakan untuk berurusan dengan koleksi dalam memori, sedangkan, IQueryableumumnya digunakan untuk memanipulasi koleksi.
Baik IEnumerable dan IQueryable digunakan untuk menyimpan koleksi data dan melakukan operasi manipulasi data, misalnya memfilter pengumpulan data. Di sini Anda dapat menemukan perbandingan perbedaan terbaik dengan contoh.
http://www.gurujipoint.com/2017/05/difference-between-ienumerable-and.html

IQueryable lebih cepat daripada IEnumerable jika kita berhadapan dengan sejumlah besar data dari database karena, IQueryable hanya mendapatkan data yang diperlukan dari database sedangkan IEnumerable mendapatkan semua data terlepas dari kebutuhan dari database
ienumerable: ketika kita ingin berurusan dengan memori inprocess, yaitu tanpa koneksi data iqueryable: kapan harus berurusan dengan sql server, yaitu dengan koneksi data ilist: operasi seperti menambah objek, menghapus objek dll