Memuat Entitas Terkait
Entity Framework mendukung tiga cara untuk memuat data terkait - pemuatan bersemangat, pemuatan malas, dan pemuatan eksplisit. Teknik yang ditunjukkan dalam topik ini berlaku sama untuk model yang dibuat dengan Perancang EF dan Code First.
Memuat dengan Bersemangat
Pemuatan bersemangat adalah proses di mana kueri untuk satu jenis entitas juga memuat entitas terkait sebagai bagian dari kueri. Pemuatan bersemangat dicapai dengan menggunakan metode Sertakan. Misalnya, kueri di bawah ini akan memuat blog dan semua postingan yang terkait dengan setiap blog.
using (var context = new BloggingContext())
{
// Load all blogs and related posts.
var blogs1 = context.Blogs
.Include(b => b.Posts)
.ToList();
// Load one blog and its related posts.
var blog1 = context.Blogs
.Where(b => b.Name == "ADO.NET Blog")
.Include(b => b.Posts)
.FirstOrDefault();
// Load all blogs and related posts
// using a string to specify the relationship.
var blogs2 = context.Blogs
.Include("Posts")
.ToList();
// Load one blog and its related posts
// using a string to specify the relationship.
var blog2 = context.Blogs
.Where(b => b.Name == "ADO.NET Blog")
.Include("Posts")
.FirstOrDefault();
}
Catatan
Sertakan adalah metode ekstensi di namespace layanan System.Data.Entity, jadi pastikan Anda menggunakan namespace tersebut.
Dengan bersemangat memuat beberapa tingkat
Dimungkinkan juga untuk dengan bersemangat memuat beberapa tingkat entitas terkait. Kueri di bawah ini memperlihatkan contoh cara melakukan ini untuk properti navigasi koleksi dan referensi.
using (var context = new BloggingContext())
{
// Load all blogs, all related posts, and all related comments.
var blogs1 = context.Blogs
.Include(b => b.Posts.Select(p => p.Comments))
.ToList();
// Load all users, their related profiles, and related avatar.
var users1 = context.Users
.Include(u => u.Profile.Avatar)
.ToList();
// Load all blogs, all related posts, and all related comments
// using a string to specify the relationships.
var blogs2 = context.Blogs
.Include("Posts.Comments")
.ToList();
// Load all users, their related profiles, and related avatar
// using a string to specify the relationships.
var users2 = context.Users
.Include("Profile.Avatar")
.ToList();
}
Catatan
Saat ini tidak dimungkinkan untuk memfilter entitas terkait mana yang dimuat. Sertakan akan selalu membawa semua entitas terkait.
Pemuatan Lambat
Pemuatan malas adalah proses di mana entitas atau kumpulan entitas secara otomatis dimuat dari database saat pertama kali properti yang mengacu pada entitas/entitas diakses. Saat menggunakan jenis entitas POCO, pemuatan malas dicapai dengan membuat instans jenis proksi turunan dan kemudian mengambil alih properti virtual untuk menambahkan hook pemuatan. Misalnya, saat menggunakan kelas entitas Blog yang ditentukan di bawah ini, Posting terkait akan dimuat pertama kali properti navigasi Posting diakses:
public class Blog
{
public int BlogId { get; set; }
public string Name { get; set; }
public string Url { get; set; }
public string Tags { get; set; }
public virtual ICollection<Post> Posts { get; set; }
}
Matikan pemuatan malas untuk serialisasi
Pemuatan malas dan serialisasi tidak bercampur dengan baik, dan jika Anda tidak berhati-hati, Anda dapat akhirnya mengkueri seluruh database Hanya karena pemuatan malas diaktifkan. Sebagian besar serializer bekerja dengan mengakses setiap properti pada instans jenis. Akses properti memicu pemuatan malas, sehingga lebih banyak entitas diserialisasikan. Pada properti entitas tersebut diakses, dan bahkan lebih banyak entitas dimuat. Ini adalah praktik yang baik untuk mematikan pemuatan malas sebelum Anda membuat serial entitas. Bagian berikut menunjukkan cara melakukan ini.
Menonaktifkan pemuatan malas untuk properti navigasi tertentu
Pemuatan malas koleksi Postingan dapat dimatikan dengan membuat properti Postingan non-virtual:
public class Blog
{
public int BlogId { get; set; }
public string Name { get; set; }
public string Url { get; set; }
public string Tags { get; set; }
public ICollection<Post> Posts { get; set; }
}
Pemuatan koleksi Postingan masih dapat dicapai menggunakan pemuatan yang bersemangat (lihat Pemuatan Bersemangat di atas) atau metode Muat (lihat Pemuatan Eksplisit di bawah).
Menonaktifkan pemuatan malas untuk semua entitas
Pemuatan malas dapat dinonaktifkan untuk semua entitas dalam konteks dengan mengatur bendera pada properti Konfigurasi. Contohnya:
public class BloggingContext : DbContext
{
public BloggingContext()
{
this.Configuration.LazyLoadingEnabled = false;
}
}
Pemuatan entitas terkait masih dapat dicapai menggunakan pemuatan bersemangat (lihat Pemuatan Bersemangat di atas) atau metode Muat (lihat Pemuatan Eksplisit di bawah).
Memuat Secara Eksplisit
Bahkan dengan pemuatan malas dinonaktifkan, masih mungkin untuk memuat entitas terkait dengan malas, tetapi harus dilakukan dengan panggilan eksplisit. Untuk melakukannya, Anda menggunakan metode Muat pada entri entitas terkait. Contoh:
using (var context = new BloggingContext())
{
var post = context.Posts.Find(2);
// Load the blog related to a given post.
context.Entry(post).Reference(p => p.Blog).Load();
// Load the blog related to a given post using a string.
context.Entry(post).Reference("Blog").Load();
var blog = context.Blogs.Find(1);
// Load the posts related to a given blog.
context.Entry(blog).Collection(p => p.Posts).Load();
// Load the posts related to a given blog
// using a string to specify the relationship.
context.Entry(blog).Collection("Posts").Load();
}
Catatan
Metode Referensi harus digunakan ketika entitas memiliki properti navigasi ke entitas tunggal lainnya. Di sisi lain, metode Koleksi harus digunakan ketika entitas memiliki properti navigasi ke kumpulan entitas lain.
Menerapkan filter saat secara eksplisit memuat entitas terkait
Metode Kueri menyediakan akses ke kueri yang mendasar yang akan digunakan Kerangka Kerja Entitas saat memuat entitas terkait. Anda kemudian dapat menggunakan LINQ untuk menerapkan filter ke kueri sebelum menjalankannya dengan panggilan ke metode ekstensi LINQ seperti ToList, Load, dll. Metode Kueri dapat digunakan dengan properti navigasi referensi dan koleksi tetapi paling berguna untuk koleksi di mana metode tersebut hanya dapat digunakan untuk memuat bagian dari koleksi. Contohnya:
using (var context = new BloggingContext())
{
var blog = context.Blogs.Find(1);
// Load the posts with the 'entity-framework' tag related to a given blog.
context.Entry(blog)
.Collection(b => b.Posts)
.Query()
.Where(p => p.Tags.Contains("entity-framework"))
.Load();
// Load the posts with the 'entity-framework' tag related to a given blog
// using a string to specify the relationship.
context.Entry(blog)
.Collection("Posts")
.Query()
.Where(p => p.Tags.Contains("entity-framework"))
.Load();
}
Saat menggunakan metode Kueri, biasanya yang terbaik adalah menonaktifkan pemuatan malas untuk properti navigasi. Ini karena jika tidak, seluruh koleksi mungkin dimuat secara otomatis oleh mekanisme pemuatan malas baik sebelum atau sesudah kueri yang difilter telah dijalankan.
Catatan
Meskipun hubungan dapat ditentukan sebagai string alih-alih ekspresi lambda, IQueryable yang dikembalikan tidak umum ketika string digunakan dan sehingga metode Cast biasanya diperlukan sebelum apa pun yang berguna dapat dilakukan dengannya.
Menggunakan Kueri untuk menghitung entitas terkait tanpa memuatnya
Terkadang berguna untuk mengetahui berapa banyak entitas yang terkait dengan entitas lain dalam database tanpa benar-benar menimbulkan biaya pemuatan semua entitas tersebut. Metode Kueri dengan metode Jumlah LINQ dapat digunakan untuk melakukan ini. Contohnya:
using (var context = new BloggingContext())
{
var blog = context.Blogs.Find(1);
// Count how many posts the blog has.
var postCount = context.Entry(blog)
.Collection(b => b.Posts)
.Query()
.Count();
}