Membuat satu Kerangka Entitas global DbContext
dalam aplikasi web sangat buruk. DbContext
kelas tidak thread-safe (dan hal yang sama berlaku untuk ObjectContext
Entity Framework v1's kelas). Ini dibangun berdasarkan konsep unit kerja
dan ini berarti Anda menggunakannya untuk mengoperasikan satu kasus penggunaan:dengan demikian untuk transaksi bisnis. Ini dimaksudkan untuk menangani satu permintaan.
Pengecualian yang Anda dapatkan terjadi karena untuk setiap permintaan Anda membuat transaksi baru, tetapi coba gunakan DbContext
yang sama . Anda beruntung karena DbContext
mendeteksi ini dan membuat pengecualian, karena sekarang Anda mengetahui bahwa ini tidak akan berhasil.
DbContext
berisi cache entitas lokal di database Anda. Ini memungkinkan Anda untuk membuat banyak perubahan dan akhirnya mengirimkan perubahan itu ke database. Saat menggunakan DbContext
statis tunggal , dengan beberapa pengguna yang memanggil SaveChanges
pada objek itu, bagaimana dia bisa tahu apa yang seharusnya dilakukan dan apa yang tidak?
Karena tidak tahu, itu akan menyelamatkan semua perubahan, tetapi pada saat itu permintaan lain mungkin masih membuat perubahan. Jika Anda beruntung, EF atau database Anda akan gagal, karena entitas dalam keadaan tidak valid. Jika Anda kurang beruntung, entitas yang berada dalam status tidak valid berhasil disimpan ke database dan Anda mungkin mengetahui beberapa minggu kemudian bahwa data Anda rusak.
Solusi untuk masalah Anda adalah membuat setidaknya satu DbContext
sesuai permintaan
. Meskipun secara teori Anda dapat men-cache konteks objek dalam sesi pengguna, ini juga merupakan ide yang buruk, karena dalam hal ini DbContext
biasanya akan hidup terlalu lama dan akan berisi data basi (karena cache internalnya tidak akan di-refresh secara otomatis).
Perhatikan juga bahwa memiliki satu DbContext
per utas sama buruknya dengan memiliki satu instance tunggal untuk aplikasi web lengkap. ASP.NET menggunakan kumpulan utas yang berarti bahwa sejumlah utas terbatas akan dibuat selama masa pakai aplikasi web. Ini pada dasarnya berarti bahwa DbContext
instance akan tetap hidup selama masa pakai aplikasi, menyebabkan masalah yang sama dengan kedaluwarsa data.
Anda mungkin berpikir bahwa memiliki satu DbContext
per utas sebenarnya aman untuk utas, tetapi ini biasanya tidak terjadi, karena ASP.NET memiliki model asinkron yang memungkinkan penyelesaian permintaan pada utas yang berbeda dari tempat dimulainya (dan versi terbaru MVC dan Web API bahkan mengizinkan jumlah utas sewenang-wenang menangani satu permintaan tunggal secara berurutan). Ini berarti bahwa utas yang memulai permintaan dan membuat ObjectContext
dapat tersedia untuk memproses permintaan lain jauh sebelum permintaan awal itu selesai. Objek yang digunakan dalam permintaan itu (seperti halaman web, pengontrol, atau kelas bisnis apa pun), mungkin masih merujuk pada DbContext
. Karena permintaan web baru berjalan di utas yang sama, permintaan tersebut akan mendapatkan DbContext
yang sama misalnya seperti yang digunakan permintaan lama. Ini sekali lagi menyebabkan kondisi balapan di aplikasi Anda dan menyebabkan masalah keamanan utas yang sama seperti yang terjadi pada DbContext
global contoh penyebab.