Menyelesaikan masalah "Sudah ada ralat DataReader ..." Ralat dalam Rangka Entiti
Kesalahan ini, "Sudah ada datareader terbuka yang berkaitan dengan arahan ini yang mesti ditutup terlebih dahulu," biasanya timbul ketika cuba melaksanakan pertanyaan pangkalan data sementara hasil pertanyaan lain masih diproses. Mari kita periksa senario biasa dan penyelesaiannya.Masalah ini sering berpunca daripada pertanyaan bersarang di mana kaedah melaksanakan pertanyaan pangkalan data dalam lelaran pertanyaan yang lebih besar. Sebagai contoh, pertimbangkan kaedah
: DateLastUpdated
<code class="language-csharp">public DateTime DateLastUpdated(long creditorRegistryId, string accountNo) { return (from h in context.AccountHistory where h.CreditorRegistryId == creditorRegistryId && h.AccountNo == accountNo select h.LastUpdated).Max(); }</code>
. Isu ini berlaku apabila digunakan dalam pertanyaan lain: LastUpdated
<code class="language-csharp">return accounts.AsEnumerable() .Select((account, index) => new AccountsReport() { // ... other properties ... DateLastUpdated = DateLastUpdated(account.CreditRegistryId, account.AccountNumber); // ... other properties ... }) // ... rest of the query ...</code>
panggilan Select
, membuka pembaca data baru. Tanpa menutup pembaca ini, operasi pangkalan data berikutnya gagal, yang membawa kepada ralat "terbuka datareader". DateLastUpdated
1. Mengaktifkan pelbagai set hasil aktif (MARS)
Penyelesaian yang paling mudah sering membolehkan Marikh dalam rentetan sambungan anda. Ini membolehkan pelbagai pembaca data aktif serentak. Ubah suai rentetan sambungan anda untuk memasukkan: MultipleActiveResultSets=True
<code class="language-csharp">connectionString = "Data Source=myServerAddress;Initial Catalog=myDatabase;MultipleActiveResultSets=True;";</code>
kaveat: Mars dapat memperkenalkan overhead prestasi dan tidak selalu penyelesaian yang ideal, terutama dengan pertanyaan kompleks.
2. Melaksanakan pemuatan bersemangat
Pendekatan yang lebih efisien dan sering disukai adalah pemuatan yang bersemangat. Daripada pertanyaan bersarang, ambil semua data yang diperlukan dalam pertanyaan tunggal menggunakan kaedah entiti Rangka Kerja:
Include
<code class="language-csharp">var accounts = from account in context.Accounts .Include(a => a.AccountHistory) // Eager load AccountHistory .Include(a => a.Gurantors) // Eager load Gurantors select new AccountsReport { // ... other properties ... DateLastUpdated = account.AccountHistory.Max(h => h.LastUpdated), // ... other properties ... };</code>
, dan Accounts
, menghapuskan keperluan pembaca data berganda dan menyelesaikan ralat. Pemuatan yang bersemangat meningkatkan prestasi dengan mengurangkan perjalanan bulat ke pangkalan data. Ingatlah untuk menyesuaikan pernyataan AccountHistory
untuk memadankan hubungan entiti khusus anda. Pertimbangkan untuk menggunakan Gurantors
untuk navigasi yang lebih mendalam jika perlu. Include
ThenInclude
memilih antara Marikh dan pemuatan yang bersemangat bergantung pada keperluan khusus aplikasi dan kerumitan pertanyaan anda. Pemuatan yang bersemangat biasanya disyorkan untuk prestasi yang lebih baik dan kod bersih, tetapi MARS menyediakan pembetulan cepat jika refactoring pertanyaan tidak dapat dilaksanakan dengan segera.
Atas ialah kandungan terperinci Mengapa saya mendapat ralat 'sudah ada ralat terbuka ...' dalam kod C# saya, dan bagaimana saya boleh memperbaikinya?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!