Apa perbedaan yang dibuat .AsNoTracking ()?

228

Saya punya pertanyaan tentang .AsNoTracking()ekstensi, karena ini semua cukup baru dan cukup membingungkan.

Saya menggunakan konteks per permintaan untuk situs web.

Banyak entitas saya tidak berubah jadi tidak perlu dilacak, tetapi saya memiliki skenario berikut di mana saya tidak yakin apa yang terjadi pada basis data, atau bahkan apakah itu membuat perbedaan dalam kasus ini.

Contoh ini adalah apa yang saya lakukan saat ini:

context.Set<User>().AsNoTracking()
// Step 1) Get user
context.Set<User>()
// Step 2) Update user

Ini sama seperti di atas tetapi menghapus .AsNoTracking()dari Langkah 1:

context.Set<User>();
// Step 1) Get user
context.Set<User>()
// Step 2) Update user

Langkah 1 & 2 menggunakan konteks yang sama tetapi terjadi pada waktu yang berbeda. Apa yang tidak bisa saya lakukan adalah apakah ada perbedaan. Karena Langkah 2 adalah pembaruan, saya kira keduanya akan mengenai database dua kali.

Adakah yang bisa memberi tahu saya apa perbedaannya?

dotnetnoob
sumber

Jawaban:

187

Perbedaannya adalah bahwa dalam kasus pertama pengguna yang diambil tidak dilacak oleh konteks sehingga ketika Anda akan menyimpan pengguna kembali ke database Anda harus melampirkannya dan menetapkan status pengguna yang benar sehingga EF tahu bahwa itu harus memperbarui pengguna yang ada alih-alih memasukkan yang baru. Dalam kasus kedua Anda tidak perlu melakukan itu jika Anda memuat dan menyimpan pengguna dengan instance konteks yang sama karena mekanisme pelacakan menanganinya untuk Anda.

Ladislav Mrnka
sumber
1
Bisakah kita mendapatkan manfaat yang sama untuk kelas anonim dalam kueri pemilihan, seperti context.Users.Select (u => new {Name = u.Name})? Terima kasih.
Dilhan Jayathilake
6
@DilhanJayathilake: Kelas anonim tidak mewakili entitas itu sendiri sehingga mereka tidak memiliki pelacakan.
Ladislav Mrnka
1
Karena EF6 membuat kunci entitas salah pada Tampilan kadang-kadang, apakah AsNoTracking () mengabaikan kunci dan karenanya menjadi alternatif untuk memperbaiki kunci secara manual (dengan asumsi manfaat kunci lainnya tidak diperlukan).
crokusek
4
Perhatikan juga, efek terbesar yang dimiliki AsNoTracking adalah bahwa pemuatan malas tidak akan berfungsi
Douglas Gaskell
170

lihat halaman ini Kerangka Entitas dan AsNoTracking

Apa yang AsNoTracking Lakukan

Entity Framework memaparkan sejumlah opsi penyesuaian kinerja untuk membantu Anda mengoptimalkan kinerja aplikasi Anda. Salah satu opsi penyetelan ini adalah .AsNoTracking(). Pengoptimalan ini memungkinkan Anda memberi tahu Entity Frameworkuntuk tidak melacak hasil kueri. Ini berarti bahwa Entity Frameworktidak melakukan pemrosesan atau penyimpanan tambahan dari entitas yang dikembalikan oleh permintaan. Namun, itu juga berarti bahwa Anda tidak dapat memperbarui entitas ini tanpa menempelkannya kembali ke grafik pelacakan.

ada keuntungan kinerja signifikan yang bisa didapat dengan menggunakan AsNoTracking

Moji
sumber
11
Tampaknya keuntungan terkadang diimbangi: stackoverflow.com/questions/9259480/…
Fabrice
3
Keuntungan kinerja saya dengan permintaan yang kompleks memuat hubungan anak orang tua dengan memasukkan dalam satu langkah sekitar 50%
Karl
53

Tidak Ada Pelacakan LINQ ke kueri Entitas

Penggunaan AsNoTracking () disarankan ketika kueri Anda dimaksudkan untuk operasi baca. Dalam skenario ini, Anda mendapatkan kembali entitas Anda tetapi mereka tidak dilacak oleh konteks Anda. Ini memastikan penggunaan memori minimal dan kinerja optimal

Pro

  1. Peningkatan kinerja dibandingkan permintaan LINQ biasa.
  2. Benda yang sepenuhnya terwujud.
  3. Paling sederhana untuk menulis dengan sintaks yang dibangun ke dalam bahasa pemrograman.

Cons

  1. Tidak cocok untuk operasi CUD.
  2. Batasan teknis tertentu, seperti: Pola yang menggunakan DefaultIfEmpty untuk kueri JOIN OUTER menghasilkan kueri yang lebih kompleks daripada pernyataan Gabung OUTER sederhana di Entity SQL.
  3. Anda masih tidak dapat menggunakan LIKE dengan pencocokan pola umum.

Info lebih lanjut tersedia di sini:

Pertimbangan kinerja untuk Kerangka Entitas

Kerangka Entitas dan NoTracking

NullReference
sumber
10

AsNoTracking () memungkinkan persyaratan "kunci unik per catatan" di EF dilewati (tidak disebutkan secara eksplisit oleh jawaban lain).

Ini sangat membantu ketika membaca Tampilan yang tidak mendukung kunci unik karena mungkin beberapa bidang dapat dibatalkan atau sifat tampilan tidak dapat diindeks secara logis.

Untuk kasus ini, "kunci" dapat disetel ke kolom yang tidak dapat dibatalkan tetapi AsNoTracking () harus digunakan dengan setiap kueri catatan lain (duplikat dengan kunci) akan dilewati.

crokusek
sumber
2
Hanya untuk menegaskan kembali pentingnya ini dengan Tampilan, saya memiliki permintaan dari tampilan yang mengembalikan 7 catatan unik ketika dijalankan melalui SSMS. Ketika dijalankan melalui EF, tanpa pengubah AsNoTracking, saya mendapatkan catatan pertama, tiga salinan dari yang kedua dan tiga salinan dari yang ketiga. Ini membutuhkan banyak goresan kepala yang tidak dapat diperbaiki untuk memperbaikinya, dan menggunakan AsNoTracking yang memperbaikinya!
Ade
Saya memiliki masalah yang sama persis ini ketika menggunakan Linq ke Entitas saat menanyakan Tampilan tanpa kunci utama. Hanya mengetahui tentang AsNoTracking setelah setengah hari menggaruk-garuk kepala. Posting forum ASP.Net ini akhirnya membawa saya ke sana. forums.asp.net/t/…
red_dorian
6

Jika Anda memiliki sesuatu yang lain mengubah DB (katakan proses lain) dan perlu memastikan Anda melihat perubahan ini, gunakan AsNoTracking(), jika tidak EF dapat memberi Anda salinan terakhir dari konteks Anda sebagai gantinya, maka itu baik untuk biasanya menggunakan konteks baru setiap permintaan :

http://codethug.com/2016/02/19/Entity-Framework-Cache-Busting/

andrew pate
sumber