Методы EntityCollection Clear () и Remove () - PullRequest
13 голосов
/ 06 октября 2010

Как правильно удалить все элементы коллекции объекта EF? В приведенном ниже коде DocumentItems представляет собой набор связанных элементов документа для документа. Этот код выполняется для Clear (), но не для SaveChanges (), поскольку связанные элементы связаны с документом через FK, а FK является обязательным. Так что я думаю, что они как-то остаются в воздухе без внешнего ключа после Clear ().

Я решаю это с помощью цикла foreach над коллекцией, вызывающей Remove () для каждого элемента, или есть другой способ?

// remove existing document items to prepare for refreshing them
existing.DocumentItems.Clear();
// adds new Document Items
PrepareInvoice(existing, collection);
_repository.SaveChanges();

Ответы [ 5 ]

13 голосов
/ 18 июля 2012

Это один из способов удаления элементов в коллекции.

VB

TEntityCollection.ToList().ForEach(Sub(o) ctx.DeleteObject(o))

C #

TEntityCollection.ToList().ForEach(x => ctx.DeleteObject(x))

Затем необходимо позвонить

ctx.SaveChanges()
11 голосов
/ 06 октября 2010

Очистить просто удаляет ссылку, но не удаляет объект.

В вашей ситуации

existing.DocumentItems.Clear();  

Все DocumentItems в EntitySet будут очищены, но вам придется удалить / удалить фактический DocumentItem или коммит с ошибкой, точно так же, как если бы вы попытались удалить его в базе данных.

Вам необходимо выполнить цикл отсоединения любых ссылок, а затем удалить сущность, которую вы хотите удалить (если только она не может быть обнуляемой и в вашей ситуации это не так)


Кроме того, я видел реализации, которые используют clear и AssociationChangedHandler для автоматического удаления старого объекта. В основном, если это изменение «удалить / удалить», оно вызывает DeleteObject () для потерянного объекта.

2 голосов
/ 09 июля 2014

Трюк: при настройке отношений между Родителем и Дочерним, вы должны создать «составной» ключ для дочернего элемента. Таким образом, когда вы говорите Родителю удалить 1 или все его дочерние элементы, связанные записи будут фактически удалены из базы данных.

Чтобы настроить составной ключ с помощью Fluent API:

modelBuilder.Entity<Child>.HasKey(t => new { t.ParentId, t.ChildId });

Затем, чтобы удалить связанных детей:

var parent = _context.Parents.SingleOrDefault(p => p.ParentId == parentId);

var childToRemove = parent.Children.First(); // Change the logic 
parent.Children.Remove(childToRemove);

// or, you can delete all children 
// parent.Children.Clear();

_context.SaveChanges();

Готово!

1 голос
/ 27 июля 2012

Да, год назад, но на небольшом примечании ... поскольку DeleteObject принимает один параметр, который имеет тот же тип, что и аргумент для лямбда-выражения, вы можете просто использовать:

entityCollection.ToList().ForEach(ctx.DeleteObject);

Я не уверен, поддерживает ли VB подобный синтаксис. Кто-нибудь? * * 1004

0 голосов
/ 25 июля 2011

Просто чтобы ответить на комментарий Nix к ответу,

мне кажется, что метод EntityCollection.Remove помечает только для удаления отношений, а не сущностей, как это делает метод EntityCollection.Clear.

Я знаю, что в документации сказано, что сущность также будет помечена для удаления, но в моем тесте я описал поведение, которое я описал (любой может объяснить, почему?).

Итак, если выЕсли в вашей концептуальной модели есть ограничение внешнего ключа один ко многим, вы не можете сохранить изменения контекста в хранилище постоянных данных.

Единственный способ, который я нашел (так как я не хочу CascadeDelete), это циклически проходитьдочерние элементы и вызывают context.DeleteObject для каждого из них, таким образом удаляя сущность и связанные отношения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...