Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Pengendalian pelacakan perilaku menentukan apakah Entity Framework Core menyimpan informasi tentang instans entitas dalam pelacak perubahannya. Jika entitas dilacak, setiap perubahan yang terdeteksi dalam entitas dipertahankan ke database selama SaveChanges. EF Core juga memperbaiki properti navigasi antara entitas dalam hasil kueri pelacakan dan entitas yang ada di pelacak perubahan.
Nota
Jenis entitas tanpa kunci tidak pernah dilacak. Di mana pun artikel ini menyebutkan jenis entitas, artikel ini mengacu pada jenis entitas yang memiliki kunci yang ditentukan.
Petunjuk / Saran
Anda dapat melihat contoh artikel ini di GitHub.
Kueri pelacakan
Secara default, kueri yang mengembalikan jenis entitas sedang dilacak. Kueri pelacakan berarti setiap perubahan pada instans entitas dipertahankan oleh SaveChanges. Dalam contoh berikut, perubahan pada peringkat blog terdeteksi dan bertahan pada database selama SaveChanges:
var blog = await context.Blogs.SingleOrDefaultAsync(b => b.BlogId == 1);
blog.Rating = 5;
await context.SaveChangesAsync();
Ketika hasil dikembalikan dalam kueri pelacakan, EF Core memeriksa apakah entitas sudah dalam konteks. Jika EF Core menemukan entitas yang sudah ada, maka instans yang sama akan dikembalikan, yang dapat menghemat memori dan meningkatkan kecepatan dibandingkan dengan kueri tanpa pelacakan. EF Core tidak menimpa nilai properti entitas saat ini dan asli dalam entri dengan nilai database. Jika entitas tidak ditemukan dalam konteks, EF Core membuat instans entitas baru dan melampirkannya ke konteks. Hasil kueri tidak berisi entitas apa pun yang ditambahkan ke konteks tetapi belum disimpan ke database.
Kueri tanpa pelacakan
Kueri tanpa pelacakan berguna saat hasilnya digunakan dalam skenario baca-saja. Mereka umumnya lebih cepat untuk dijalankan karena tidak perlu menyiapkan informasi pelacakan perubahan. Jika entitas yang diambil dari database tidak perlu diperbarui, maka kueri tanpa pelacakan harus digunakan. Kueri individual dapat diatur menjadi tanpa pelacakan. Kueri tanpa pelacakan juga memberikan hasil berdasarkan apa yang ada dalam database yang mengacuhkan perubahan lokal atau entitas tambahan.
var blogs = await context.Blogs
.AsNoTracking()
.ToListAsync();
Perilaku pelacakan default dapat diubah pada tingkat instans konteks:
context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
var blogs = await context.Blogs.ToListAsync();
Bagian berikutnya menjelaskan kapan kueri tanpa pelacakan mungkin kurang efisien daripada kueri pelacakan.
Resolusi identitas
Karena kueri pelacakan menggunakan pelacak perubahan, EF Core melakukan resolusi identitas dalam kueri pelacakan. Saat mewujudkan entitas, EF Core mengembalikan instans entitas yang sama dari pelacak perubahan jika sudah dilacak. Jika hasilnya berisi entitas yang sama beberapa kali, instans yang sama dikembalikan untuk setiap kemunculan. Kueri tanpa pelacakan:
- Jangan gunakan pelacak perubahan dan jangan lakukan resolusi identitas.
- Kembalikan instans baru dari entitas bahkan ketika entitas yang sama muncul beberapa kali dalam hasil.
Pelacakan dan tanpa pelacakan dapat digabungkan dalam kueri yang sama. Artinya, Anda dapat memiliki kueri tanpa pelacakan, yang melakukan resolusi identitas dalam hasil. Sama seperti operator AsNoTracking yang dapat dikueri, kami telah menambahkan operator lain AsNoTrackingWithIdentityResolution<TEntity>(IQueryable<TEntity>). Ada juga entri terkait yang ditambahkan dalam QueryTrackingBehavior enum. Saat kueri untuk menggunakan resolusi identitas dikonfigurasi tanpa pelacakan, pelacak perubahan yang berdiri sendiri digunakan di latar belakang saat menghasilkan hasil kueri sehingga setiap instans hanya diwujudkan sekali. Karena pelacak perubahan ini berbeda dari yang ada dalam konteks, hasilnya tidak dilacak oleh konteks. Setelah kueri dijumlahkan sepenuhnya, pelacak perubahan keluar dari ruang lingkup dan dibuang oleh sistem sesuai kebutuhan.
var blogs = await context.Blogs
.AsNoTrackingWithIdentityResolution()
.ToListAsync();
Mengonfigurasi perilaku pelacakan default
Jika Anda menemukan diri Anda mengubah perilaku pelacakan untuk banyak kueri, Anda mungkin ingin mengubah default sebagai gantinya:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder
.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=EFQuerying.Tracking;Trusted_Connection=True;ConnectRetryCount=0")
.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
}
Ini membuat semua kueri Anda secara otomatis tidak dilacak. Anda masih dapat menambahkan AsTracking untuk membuat pelacakan kueri tertentu.
Pelacakan dan proyeksi kustom
Bahkan jika jenis hasil kueri bukan jenis entitas, EF Core masih akan melacak jenis entitas yang terkandung dalam hasil secara default. Dalam kueri berikut, yang mengembalikan jenis anonim, instans Blog dalam kumpulan hasil akan dilacak.
var blog = context.Blogs
.Select(
b =>
new { Blog = b, PostCount = b.Posts.Count() });
Jika kumpulan hasil berisi jenis entitas yang keluar dari komposisi LINQ, EF Core akan melacaknya.
var blog = context.Blogs
.Select(
b =>
new { Blog = b, Post = b.Posts.OrderBy(p => p.Rating).LastOrDefault() });
Jika kumpulan hasil tidak berisi jenis entitas apa pun, maka tidak ada pelacakan yang dilakukan. Dalam kueri berikut, kami mengembalikan tipe anonim dengan beberapa nilai dari tipe entitas, tetapi tidak ada contoh dari tipe entitas yang sesungguhnya. Tidak ada entitas terlacak yang keluar dari kueri.
var blog = context.Blogs
.Select(
b =>
new { Id = b.BlogId, b.Url });
EF Core mendukung melakukan evaluasi klien dalam proyeksi tingkat atas. Jika EF Core mewujudkan instans entitas untuk evaluasi klien, instans tersebut akan dilacak. Di sini, karena kami meneruskan blog entitas ke metode di sisi klien StandardizeURL, EF Core juga akan melacak instans blog.
var blogs = await context.Blogs
.OrderByDescending(blog => blog.Rating)
.Select(
blog => new { Id = blog.BlogId, Url = StandardizeUrl(blog) })
.ToListAsync();
public static string StandardizeUrl(Blog blog)
{
var url = blog.Url.ToLower();
if (!url.StartsWith("http://"))
{
url = string.Concat("http://", url);
}
return url;
}
EF Core tidak melacak instans entitas tanpa kunci yang terkandung dalam hasilnya. Tetapi EF Core melacak semua instans jenis entitas lainnya dengan kunci sesuai dengan aturan di atas.
Versi sebelumnya
Sebelum versi 3.0, EF Core memiliki beberapa perbedaan dalam cara pelacakan dilakukan. Perbedaan penting adalah sebagai berikut:
Seperti yang dijelaskan di halaman Evaluasi Klien vs Server, evaluasi klien didukung oleh EF Core di bagian mana pun dari kueri sebelum versi 3.0. Evaluasi klien menyebabkan materialisasi entitas, yang bukan bagian dari hasilnya. Jadi EF Core menganalisis hasilnya untuk mendeteksi apa yang harus dilacak. Desain ini memiliki perbedaan tertentu sebagai berikut:
Evaluasi klien dalam proyeksi, yang menyebabkan terwujudnya tetapi tidak mengembalikan instans entitas yang terwujud tersebut tidak dilacak. Contoh berikut ini tidak melacak entitas
blog.var blogs = await context.Blogs .OrderByDescending(blog => blog.Rating) .Select( blog => new { Id = blog.BlogId, Url = StandardizeUrl(blog) }) .ToListAsync();EF Core tidak melacak objek yang keluar dari komposisi LINQ dalam kasus tertentu. Contoh berikut tidak berhasil melacak
Post.var blog = context.Blogs .Select( b => new { Blog = b, Post = b.Posts.OrderBy(p => p.Rating).LastOrDefault() });
Setiap kali hasil kueri berisi jenis entitas tanpa kunci, seluruh kueri dibuat sebagai non-pelacakan. Itu berarti bahwa jenis entitas dengan kunci, yang terdapat dalam hasil, juga tidak sedang dilacak.
EF Core digunakan untuk melakukan resolusi identitas dalam kueri tanpa pelacakan. Ini menggunakan referensi yang lemah untuk melacak entitas yang telah dikembalikan. Jadi, jika kumpulan hasil berisi beberapa kali entitas yang sama, Anda akan mendapatkan instans yang sama untuk setiap kemunculan. Meskipun jika hasil sebelumnya dengan identitas yang sama keluar dari cakupan dan mendapatkan sampah yang dikumpulkan, EF Core mengembalikan instans baru.