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 IQueryable
dikembalikan, masing-masing.
AsQueryable()
hanya akan melemparkan enumerable ke queryable dan mengembalikannya jika itu mengimplementasikan IQueryable
antarmuka, jika tidak membungkusnya dalam ConstantExpression
, yang disebut dalam EnumerableQuery
objek yang dikembalikan .
Perbedaan utama adalah bahwa operator LINQ untuk IQueryable<T>
mengambil Expression
objek 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:
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 IQueryable
antarmuka diturunkan IEnumerable
, jadi apa pun yang IEnumerable
bisa dilakukan, IQueryable
juga bisa dilakukan.
Ada banyak perbedaan tetapi mari kita bahas tentang satu perbedaan besar yang membuat perbedaan terbesar. IEnumerable
antarmuka berguna ketika koleksi Anda dimuat menggunakan LINQ
atau kerangka kerja Entity dan Anda ingin menerapkan filter pada koleksi.
Pertimbangkan kode sederhana di bawah ini yang digunakan IEnumerable
dengan kerangka kerja entitas. Ini menggunakan Where
filter untuk mendapatkan catatan yang EmpId
adalah 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 IEnumerable
kode berada. Dengan kata lain semua data diambil dari database dan kemudian pada klien scan dan mendapat catatan dengan EmpId
itu 2
.
Tapi sekarang lihat di bawah kode yang kami telah berubah IEnumerable
ke 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 IQueryable
dan IEnumerable
tentang 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 IEnumerable
adalah 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 Employee
tabel dalam database. Saya menambahkan item Model Data Entitas ADO.NET ke dalam aplikasi konsol saya yang menunjuk ke Employee
tabel 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 IEnumerable
dibawa semua 5 catatan hadir dalam Salary
tabel 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 IEnumerable
dan IQueryable
untuk memanipulasi data yang diambil dari basis data. IQueryable
mewarisi dari IEnumerable
, demikian IQueryable
juga mengandung semua IEnumerable
fitur. Perbedaan utama antara IQueryable
dan IEnumerable
adalah yang IQueryable
mengeksekusi kueri dengan filter sedangkan IEnumerable
mengeksekusi kueri pertama dan kemudian menyaring data berdasarkan kondisi.
Temukan diferensiasi lebih rinci di bawah ini:
Tidak terhitung
IEnumerable
ada di System.Collections
namespaceIEnumerable
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
IQueryable
ada di System.Linq
namespaceIQueryable
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 IEnumerable
umumnya digunakan untuk berurusan dengan koleksi dalam memori, sedangkan, IQueryable
umumnya 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