Kerangka Entitas .Hapus () vs. .DeleteObject ()

Jawaban:

275

Secara umum tidak benar bahwa Anda dapat " menghapus item dari database " dengan kedua metode. Lebih tepatnya seperti:

  • ObjectContext.DeleteObject(entity)menandai entitas sepertiDeleted dalam konteksnya. (Ini EntityStateadalah Deletedsetelah itu.) Jika Anda menelepon SaveChangessetelah EF mengirimkan SQL DELETEpernyataan ke database. Jika tidak ada batasan referensi dalam basis data yang dilanggar, entitas akan dihapus, jika tidak maka pengecualian dilemparkan.

  • EntityCollection.Remove(childEntity)menandai hubungan antara orang tua dan childEntitysebagaiDeleted . Jika childEntityitu sendiri dihapus dari database dan apa yang sebenarnya terjadi ketika Anda menelepon SaveChangestergantung pada jenis hubungan antara keduanya:

    • Jika hubungan itu opsional , yaitu kunci asing yang merujuk dari anak ke induk dalam database memungkinkan NULLnilai, asing ini akan disetel ke nol dan jika Anda memanggil nilai SaveChangesini NULLmaka childEntityakan ditulis ke database (yaitu hubungan antara keduanya dihapus). Ini terjadi dengan UPDATEpernyataan SQL . Tidak ada DELETEpernyataan yang muncul.

    • Jika hubungan diperlukan (FK tidak mengizinkan NULLnilai) dan hubungan itu tidak mengidentifikasi (yang berarti bahwa kunci asing bukan bagian dari kunci primer anak (komposit) anak Anda harus menambahkan anak ke orang tua lain atau Anda harus menghapus anak secara eksplisit (dengan DeleteObjectitu). Jika Anda tidak melakukan salah satu dari ini, kendala referensial dilanggar dan EF akan mengeluarkan pengecualian ketika Anda menelepon SaveChanges- yang terkenal " Hubungan tidak dapat diubah karena satu atau lebih properti kunci asing tidak dapat dibatalkan " pengecualian atau serupa.

    • Jika hubungan ini mengidentifikasi (itu tentu diperlukan kemudian karena setiap bagian dari kunci primer tidak dapat NULL) EF akan menandai childEntitysebagai Deletedjuga. Jika Anda memanggil pernyataan SaveChangesSQL DELETEakan dikirim ke database. Jika tidak ada batasan referensial lain dalam basis data yang dilanggar, entitas akan dihapus, jika tidak ada pengecualian yang dilemparkan.

Saya sebenarnya agak bingung tentang bagian Keterangan pada halaman MSDN yang telah Anda tautkan karena dikatakan: " Jika hubungan memiliki batasan integritas referensial, memanggil metode Hapus pada objek dependen menandai hubungan dan objek dependen untuk dihapus. ". Ini tampaknya tidak aman atau bahkan salah bagi saya karena ketiga kasus di atas memiliki " batasan integritas referensial " tetapi hanya dalam kasus terakhir anak tersebut sebenarnya dihapus. (Kecuali jika maksudnya dengan " objek dependen " objek yang berpartisipasi dalam hubungan identifikasi yang akan menjadi terminologi yang tidak biasa.)

Slauma
sumber
2
Referensi integritas wikipedia: Integritas referensial adalah properti data yang, ketika puas, mengharuskan setiap nilai dari satu atribut (kolom) dari suatu relasi (tabel) untuk ada sebagai nilai atribut lain dalam relasi yang berbeda (atau sama) (tabel) ), jadi ketika hubungan Opsional, kami melanggar aturan Integritas data
Mohammadreza
3
@ Mohammadreza: Jika Anda menafsirkan NULLsebagai "Bukan nilai" (bukan "nilai NULL" seperti yang saya tulis kadang-kadang agak ceroboh) maka "hubungan opsional" tidak bertentangan dengan definisi integritas referensial.
Slauma
1
Jadi apa versi EF Core ObjectContext.DeleteObject?
Jonathan Allen
13

Jika Anda benar-benar ingin menggunakan Dihapus, Anda harus membuat kunci asing Anda nullable, tetapi kemudian Anda akan berakhir dengan catatan yatim (yang merupakan salah satu alasan utama Anda tidak boleh melakukan itu di tempat pertama). Jadi gunakan sajaRemove()

ObjectContext.DeleteObject (entitas) menandai entitas sebagai Dihapus dalam konteks. (EntityState dihapus setelah itu.) Jika Anda memanggil SaveChanges setelah itu EF mengirim pernyataan SQL DELETE ke database. Jika tidak ada batasan referensi dalam basis data yang dilanggar, entitas akan dihapus, jika tidak maka pengecualian dilemparkan.

EntityCollection.Remove (childEntity) menandai hubungan antara induk dan childEntity sebagai Dihapus. Jika childEntity sendiri dihapus dari basis data dan apa yang sebenarnya terjadi ketika Anda memanggil SaveChanges tergantung pada jenis hubungan antara keduanya:

Satu hal yang patut dicatat adalah bahwa pengaturan .State = EntityState.Deleted tidak memicu perubahan yang terdeteksi secara otomatis. ( arsip )

Matas Vaitkevicius
sumber
4
Ok, bagi mereka yang memberikan suara rendah pada jawaban saya tidak ada hubungannya dengan Slauma - keduanya menunjukkan dokumentasi yang sama . Milik saya menjelaskan contoh kehidupan nyata sementara teorinya bagian dari itu.
Matas Vaitkevicius