Saya menghapus beberapa item dari tabel menggunakan Entity Framework. Tidak ada objek kunci asing / induk jadi saya tidak bisa menangani ini dengan OnDeleteCascade.
Saat ini saya sedang melakukan ini:
var widgets = context.Widgets
.Where(w => w.WidgetId == widgetId);
foreach (Widget widget in widgets)
{
context.Widgets.DeleteObject(widget);
}
context.SaveChanges();
Ini bekerja tetapi foreach menggangguku. Saya menggunakan EF4 tetapi saya tidak ingin menjalankan SQL. Saya hanya ingin memastikan saya tidak melewatkan apa pun - ini sebagus yang didapat, bukan? Saya bisa abstrak dengan metode ekstensi atau pembantu, tetapi di suatu tempat kita masih akan melakukan foreach, kan?
entity-framework
Jon Galloway
sumber
sumber
Jawaban:
Jika Anda tidak ingin menjalankan SQL langsung memanggil DeleteObject dalam satu lingkaran adalah yang terbaik yang dapat Anda lakukan hari ini.
Namun Anda dapat menjalankan SQL dan tetap membuatnya menjadi tujuan umum sepenuhnya melalui metode ekstensi, menggunakan pendekatan yang saya jelaskan di sini .
Meskipun jawaban itu untuk 3.5. Untuk 4.0 saya mungkin akan menggunakan API ExecuteStoreCommand baru di bawah tenda, alih-alih turun ke StoreConnection.
sumber
EntityFramework 6 membuatnya lebih mudah
.RemoveRange()
.Contoh:
sumber
Ya, kecuali Anda bisa membuatnya menjadi dua baris:
sumber
sumber
WHERE IN ({0})
, dan argumen kedua seharusnyaString.Join(",", idList)
.EntityFramework.Extended
String.Join
, Anda mungkin perlu menggunakanstring.Format
dan meneruskan string SQL yang sudah terbentuk ke perintah. Selama daftar Anda hanya memiliki bilangan bulat, tidak ada risiko serangan injeksi. Periksa pertanyaan ini: bagaimana saya bisa meneruskan array ke perintah eksekusi toko?Saya tahu ini cukup terlambat tetapi jika seseorang membutuhkan solusi sederhana, hal yang keren adalah Anda juga dapat menambahkan klausa di mana dengannya:
Catatan: baru diuji dengan MSSQL2008.
Memperbarui:
Solusi di atas tidak akan berfungsi ketika EF menghasilkan pernyataan sql dengan parameter , jadi inilah pembaruan untuk EF5 :
Ini membutuhkan sedikit refleksi tetapi bekerja dengan baik.
sumber
Bagi siapa pun yang menggunakan EF5, pustaka ekstensi berikut dapat digunakan: https://github.com/loresoft/EntityFramework.Extended
sumber
Delete()
fungsi di entitas saya di EF6.context.Widgets.Where(w => w.WidgetId == widgetId).Delete();
adalah cara yang lebih baru dengan EntityFramework.ExtendedTampaknya masih gila harus menarik kembali apa pun dari server hanya untuk menghapusnya, tetapi paling tidak mendapatkan kembali ID saja jauh lebih ramping daripada menarik entitas lengkap:
sumber
Widget
objek rintisan Anda hanya memilikiId
properti yang diinisialisasi . Cara mengatasinya adalah dengan menggunakancontext.Configuration.ValidateOnSaveEnabled = false
(setidaknya di EF6). Ini menonaktifkan validasi Entity Framework sendiri, tetapi tentu saja tetap melakukan validasi database sendiri.delete
dengan solusi yang sama untukupdate
ing entitas tanpa memuatnya.EF 6.1
Pemakaian:
sumber
Untuk EF 4.1,
sumber
Anda bisa menggunakan ekstensi library untuk melakukannya seperti EntityFramework.Extended atau Z.EntityFramework.Plus.EF6, ada tersedia untuk EF 5, 6 atau Core. Pustaka ini memiliki kinerja yang hebat ketika Anda harus menghapus atau memperbarui dan mereka menggunakan LINQ. Contoh untuk menghapus ( sumber plus ):
ctx.Users.Where(x => x.LastLoginDate < DateTime.Now.AddYears(-2)) .Delete();
atau ( sumber diperluas )
context.Users.Where(u => u.FirstName == "firstname") .Delete();
Ini menggunakan pernyataan SQL asli, jadi kinerjanya bagus.
sumber
Cara tercepat untuk menghapus menggunakan prosedur tersimpan. Saya lebih suka prosedur yang tersimpan dalam proyek database daripada SQL dinamis karena penggantian nama akan ditangani dengan benar dan memiliki kesalahan penyusun. SQL dinamis bisa merujuk ke tabel yang telah dihapus / diganti namanya menyebabkan kesalahan waktu berjalan.
Dalam contoh ini, saya memiliki dua Daftar tabel dan Daftar item. Saya perlu cara cepat untuk menghapus semua ListItems dari daftar yang diberikan.
Sekarang bagian yang menarik dari menghapus item dan memperbarui kerangka kerja Entity menggunakan ekstensi.
Kode utama sekarang dapat menggunakannya adalah sebagai
sumber
Jika Anda ingin menghapus semua baris tabel, Anda bisa menjalankan perintah sql
TRUNCATE TABLE (Transact-SQL) Menghapus semua baris dari tabel tanpa mencatat penghapusan baris individu. TRUNCATE TABLE mirip dengan pernyataan DELETE tanpa klausa WHERE; Namun, TRUNCATE TABLE lebih cepat dan menggunakan lebih sedikit sumber daya sistem dan log transaksi.
sumber
truncate table
di tabel yang direferensikan oleh batasan KUNCI ASING. (Anda dapat memotong tabel yang memiliki kunci asing yang mereferensikannya sendiri.). Dokumentasi MSDNUUHHIVS
Ini adalah cara yang sangat elegan dan cepat untuk menghapus batch, tetapi harus digunakan dengan hati-hati:context.SaveChanges()
Masalah-masalah ini dapat diatasi dengan mengendalikan transaksi. Kode berikut mengilustrasikan bagaimana cara batch batch menghapus dan memasukkan secara transaksional:
sumber
Inti Kerangka Entitas
Ringkasan :
Komentar :
sumber
Anda dapat menjalankan kueri sql secara langsung sebagai berikut:
Untuk pilih kita dapat menggunakan
sumber
Anda juga dapat menggunakan metode DeleteAllOnSubmit () dengan meneruskannya hasil Anda dalam daftar generik daripada di var. Dengan cara ini, foreach Anda mengurangi menjadi satu baris kode:
Mungkin masih menggunakan loop secara internal.
sumber
var
.Jawaban Thanh bekerja paling baik untuk saya. Menghapus semua catatan saya dalam satu perjalanan server. Saya kesulitan benar-benar memanggil metode ekstensi, jadi saya pikir saya akan berbagi milik saya (EF 6):
Saya menambahkan metode ekstensi ke kelas pembantu di proyek MVC saya dan mengubah nama menjadi "RemoveWhere". Saya menyuntikkan dbContext ke dalam pengontrol saya, tetapi Anda juga bisa melakukannya
using
.Ini menghasilkan pernyataan penghapusan tunggal untuk grup.
sumber
EF 6. =>
sumber
Terbaik:
in EF6 => .RemoveRange()
Contoh:
sumber
Lihat jawaban 'bit kode favorit' yang berfungsi
Inilah cara saya menggunakannya:
sumber
Di EF 6.2 ini bekerja dengan sempurna, mengirim penghapusan langsung ke database tanpa terlebih dahulu memuat entitas:
Dengan predikat tetap, ini cukup mudah:
Dan jika Anda memerlukan predikat dinamis, lihat LINQKit (paket Nuget tersedia), sesuatu seperti ini berfungsi dengan baik dalam kasus saya:
sumber
Z.EntityFramework.Plus
atau yang serupa? ( entitasframework.net/batch-delete )Delete()
metode secara inheren tidak ada).