Apa yang dilakukan Include () di LINQ?

96

Saya mencoba melakukan banyak penelitian tetapi saya lebih seperti orang db - jadi bahkan penjelasan di MSDN tidak masuk akal bagi saya. Adakah yang bisa menjelaskan, dan memberikan beberapa contoh tentang Include()pernyataan apa yang dilakukan dalam istilah SQLkueri?

CJ
sumber
Sangat mendasar, saya hanya tahu Select, Where, Order by, beberapa operator agregat. Saya belum mencoba JOIN di LINQ, atau Include. Tujuan akhir saya adalah dapat menulis ulang LINQ Queries ini ke dalam SQL
CJ

Jawaban:

169

Katakanlah misalnya Anda ingin mendapatkan daftar semua pelanggan Anda:

var customers = context.Customers.ToList();

Dan mari kita asumsikan bahwa setiap Customerobjek memiliki referensi ke himpunannya Orders, dan masing-masing Ordermemiliki referensi LineItemsyang juga dapat mereferensikan a Product.

Seperti yang Anda lihat, memilih objek tingkat atas dengan banyak entitas terkait dapat menghasilkan kueri yang perlu menarik data dari banyak sumber. Sebagai ukuran kinerja, Include()memungkinkan Anda untuk menunjukkan entitas terkait mana yang harus dibaca dari database sebagai bagian dari kueri yang sama.

Menggunakan contoh yang sama, ini mungkin membawa semua tajuk pesanan terkait, tetapi tidak ada catatan lain:

var customersWithOrderDetail = context.Customers.Include("Orders").ToList();

Sebagai poin terakhir sejak Anda meminta SQL, pernyataan pertama tanpa Include()dapat menghasilkan pernyataan sederhana:

SELECT * FROM Customers;

Pernyataan terakhir yang memanggil Include("Orders")mungkin terlihat seperti ini:

SELECT *
FROM Customers JOIN Orders ON Customers.Id = Orders.CustomerId;
Yuck
sumber
1
Terima kasih. Menggunakan contoh Anda, dapatkah saya mengatakan jika saya juga ingin menyertakan LineItemsdan Products, kueri LINQ akan terlihat seperti ini var customersWithOrderDetail = context.Customers.Include("Orders").Include("LineItems").Include("Products").ToList();:?
CJ
2
Ya, Anda dapat menghubungkan beberapa panggilan ke Include()untuk menangkap objek di sepanjang "jalur" yang berbeda. Jika Anda menginginkan objek di jalur yang sama, Anda hanya perlu melakukan satu panggilan yang menentukan seluruh jalur. Karena LineItemsdan Productstidak berbagi komponen jalur apa pun, Anda memerlukan panggilan terpisah.
Yuck
Apakah wajib menggunakan Include? Saya cukup yakin saya mengerjakan solusi di mana saya bisa mendapatkan objek terkait tanpa menggunakannya.
Jepzen
@Jepzen Itu tergantung pada apakah Anda menggunakan entitas yang lambat dimuat atau tidak.
Yuck
@Yuck, saya yakin ini berfungsi saat Anda menggunakan pemuatan lambat, dalam kasus eager loading, Anda tidak perlu menggunakan pernyataan "include", tetapi ini pasti akan mengakibatkan masalah kinerja. Harap perbaiki saya tentang ini.
sam
27

Saya hanya ingin menambahkan bahwa "Sertakan" adalah bagian dari eager loading. Ini dijelaskan dalam tutorial Entity Framework 6 oleh Microsoft. Ini tautannya: https://docs.microsoft.com/en-us/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/reading-related-data-with-the -entity-framework-in-an-asp-net-mvc-application


Kutipan dari halaman tertaut:

Berikut adalah beberapa cara Entity Framework dapat memuat data terkait ke dalam properti navigasi dari suatu entitas:

Pemuatan lambat. Saat entitas pertama kali dibaca, data terkait tidak diambil. Namun, saat pertama kali Anda mencoba mengakses properti navigasi, data yang diperlukan untuk properti navigasi tersebut diambil secara otomatis. Ini menghasilkan beberapa kueri yang dikirim ke database - satu untuk entitas itu sendiri dan satu lagi setiap kali data terkait untuk entitas harus diambil. Kelas DbContext mengaktifkan pemuatan lambat secara default.

Memuat dengan bersemangat. Saat entitas dibaca, data terkait diambil bersamanya. Ini biasanya menghasilkan kueri gabungan tunggal yang mengambil semua data yang diperlukan. Anda menentukan eager loading dengan menggunakan Includemetode ini.

Pemuatan eksplisit. Ini mirip dengan lazy loading, kecuali bahwa Anda secara eksplisit mengambil data terkait dalam kode; ini tidak terjadi secara otomatis saat Anda mengakses properti navigasi. Anda memuat data terkait secara manual dengan mendapatkan entri manajer status objek untuk entitas dan memanggil metode Collection.Load untuk koleksi atau metode Reference.Load untuk properti yang memiliki entitas tunggal. (Dalam contoh berikut, jika Anda ingin memuat properti navigasi Administrator, Anda akan menggantinya Collection(x => x.Courses)dengan Reference(x => x.Administrator).) Biasanya Anda akan menggunakan pemuatan eksplisit hanya ketika Anda mematikan pemuatan lambat.

Karena mereka tidak segera mengambil nilai properti, lazy loading dan eksplisit loading juga disebut sebagai deferred loading.

Minoosha
sumber
3
Selamat datang di SO =) Hanya sebuah saran tetapi ketika Anda menjawab sesuatu seperti itu, jika Anda bisa, sertakan potongan kode. Sayangnya, tautan bisa mati.
The_Cthulhu_Kid
2

Anggap saja sebagai memaksakan Eager-Loading dalam skenario di mana Anda sub-item akan menjadi pemuatan lambat.

Query EF yang dikirim ke database akan menghasilkan hasil yang lebih besar pada awalnya, tetapi pada akses tidak ada permintaan tindak lanjut yang akan dibuat saat mengakses item yang disertakan.

Di sisi lain, tanpa itu, EF akan mengeksekusi query terpisah nanti, saat Anda mengakses sub-item pertama kali.

robkrueger
sumber