Entity Framework. Усуньте () проти .DeleteObject ()


141

Ви можете видалити елемент із бази даних за допомогою EF, використовуючи наступні два способи.

Перший - на, EntityCollectionа другий - на ObjectContext.

Коли кожен слід використовувати?

Чи один віддає перевагу іншому?

Remove()повертає a boolі DeleteObject()повертається void.

Відповіді:


275

Зазвичай не правильно, що ви можете " видалити елемент із бази даних " двома методами. Якщо бути точним, це так:

  • ObjectContext.DeleteObject(entity)позначає сутність якDeleted у контексті. (Це EntityStateє Deletedпісля цього.) Якщо ви телефонуєте SaveChangesпісля EF посилає SQL DELETEоператор в базу даних. Якщо жодні референтні обмеження в базі даних не порушені, сутність буде видалена, інакше буде викинуто виняток.

  • EntityCollection.Remove(childEntity)позначає відносини між батьком і childEntityякDeleted . Якщо ви childEntityвидалите саму базу даних і що саме відбувається під час дзвінка, SaveChangesзалежить від типу відносин між цими:

    • Якщо взаємозв'язок необов'язковий , тобто зовнішній ключ, який посилається від дочірнього батька в базі даних, дозволяє NULLзначення, цей іноземний буде встановлений на нульове значення, і якщо ви будете викликати SaveChangesце NULLзначення для childEntityволі, буде записано в базу даних (тобто відносини між обидва видаляються). Це відбувається з оператором SQL UPDATE. Жодного DELETEтвердження не відбувається.

    • Якщо зв'язок необхідний (FK не дозволяє NULLзначення) і співвідношення не є ідентифікаційним (це означає, що зовнішній ключ не є частиною первинного ключа дитини), ви повинні або додати дитину до іншого батька, або ви повинні явно видалити дитину (з DeleteObjectпотім). Якщо ви не зробите жодне з цих референтних обмежень, порушується, і EF викине виняток, коли ви телефонуєте SaveChanges- сумнозвісний " Відносини не вдалося змінити, оскільки одна чи більше властивостей іноземного ключа не є нульовими " виняток або подібний.

    • Якщо ви зателефонуєте, оператор SQL буде надісланий до бази даних. Якщо жодні інші референтні обмеження в базі даних не порушені, сутність буде видалена, інакше буде викинуто виняток.NULLchildEntityDeletedSaveChangesDELETE

Я насправді трохи розгублений з приводу розділу "Зауваження" на сторінці MSDN, на який ви пов’язали, оскільки він говорить: " Якщо у відносини є референтне обмеження цілісності, виклик методу" Видалити "на залежному об'єкті позначає як відношення, так і залежний об'єкт для видалення. ". Мені це здається неточним або навіть неправильним, оскільки всі три вищезазначені випадки мають " референтне обмеження цілісності ", але лише в останньому випадку дитина фактично видаляється. (Якщо вони не мають на увазі під " залежним об'єктом " об'єкт, який бере участь у виявленні відносин, що було б незвичною термінологією.)


2
Вікіпедія відсилальної цілісності: Цілісність посилань - це властивість даних, яка, задовольняючи, вимагає, щоб кожне значення одного атрибута (стовпця) відношення (таблиці) існувало як значення іншого атрибута в іншому (або тому самому) відношенні (таблиця ), тож коли відносини необов’язкові, ми порушуємо правило цілісності даних
Мохаммадреза

3
@Mohammadreza: Якщо ви інтерпретуєте NULLяк "Не значення" (замість "значення NULL", як я писав, іноді трохи неохайно), то "необов'язковий зв'язок" не суперечить цьому визначенню референтної цілісності.
Слаума

1
То яка версія EF Core ObjectContext.DeleteObject?
Джонатан Аллен

13

Якщо ви дійсно хочете скористатися видаленими, вам доведеться зробити свої зовнішні ключі нульовими, але тоді ви закінчитеся з осиротілими записами (що є однією з головних причин, коли ви не повинні робити це в першу чергу). Тому просто використовуйтеRemove()

ObjectContext.DeleteObject (сутність) позначає об'єкт видаленим у контексті. (Після цього видаляється EntityState.) Якщо після цього ви зателефонуєте SaveChanges, EF посилає в базу даних оператор SQL DELETE. Якщо жодні референтні обмеження в базі даних не порушені, сутність буде видалена, інакше буде викинуто виняток.

EntityCollection.Remove (childEntity) позначає видалені відносини між батьком та childEntity. Якщо ви самі видаляєте базу даних childEntity, і що саме відбувається при виклику SaveChanges, залежить від типу відносин між цими двома:

Варто зазначити, що налаштування .State = EntityState.Deleted не запускає автоматично виявлені зміни. ( архів )


4
Гаразд, для тих, хто голосує моєю відповіддю, це не має нічого спільного з Слаумою - вони обоє вказують на ту саму документацію . Мойн пояснює приклади реального життя, в той час як його теорія є частиною цього.
Матас Вайткевічус
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.