Удаление каскада с помощью DbContext и Entity Framework 6

.net entity-framework entity-framework-6

Вопрос

Есть ли способ каскадировать объекты удаления без изменения внешних ключей в БД и без изменения edmx? У меня есть БД с более чем 100 таблицами, на которые ссылаются внешние ключи с помощью Delete Rule = No Action.

Я нашел этот красивый код в книге «Entity Framework 6 Recipes». Но это для ObjectContext и мне нужно для DbContext .

    private static void DeleteRelatedEntities<T>(T entity, test123Entities1 context)
        where T : EntityObject
    {
        var entities =
            ((IEntityWithRelationships) entity).RelationshipManager.GetAllRelatedEnds()
                .SelectMany(e => e.CreateSourceQuery().OfType<EntityObject>())
                .ToList();

        foreach (var child in entities)
        {
            DeleteRelatedEntities(child, context);
            context.DeleteObject(child);
        }
        context.SaveChanges();
    } 

Этот метод можно использовать с этим преобразованием

    private static void DeleteRelatedEntities<T>(T entity, test123Entities1 context)
        where T : EntityObject
    {
        var entities =
            ((IEntityWithRelationships) entity).RelationshipManager.GetAllRelatedEnds()
                .SelectMany(e => e.CreateSourceQuery().OfType<EntityObject>())
                .ToList();

        foreach (var child in entities)
        {
            DeleteRelatedEntities(child, context);
            context.DeleteObject(child);
        }
        context.SaveChanges();
    } 

но тогда мне также нужен аналогичный адаптер для преобразования моего POCO в EntityObject.

Какие-либо предложения?

Спасибо.

Популярные ответы

Это код BAD .

  1. Это даже не работает. Это не удается с помощью StackOverflowException - проверено прямо сейчас, скопировав фрагмент кода в мое тестовое решение.
  2. Это не каскадное удаление. Cascade delete происходит в базе данных (если у вас уже нет сущностей), но этот код всегда выполняет запросы во всех свойствах навигации для загрузки объектов и помечает их как удаленные в приложении. Это создает ужасные накладные расходы, передавая все эти данные из базы данных в ваше приложение.
  3. Слово all в предыдущем параграфе действительно означает all = оно не учитывает нормальный поток каскадного удаления (от родителя к детям). Этот метод также может протекать в обратном направлении (от детей к родительскому), а также потому, что он рекурсивно будет загружаться и удаляться. Это означает, что от ребенка вы можете легко удалить значительную часть своей базы данных !!!
  4. Если у вас есть свойство навигации как для дочернего, так и для родительского объекта, вы получите бесконечный цикл!
  5. SaveChanges вызывается в рекурсивной функции - каждое выполнение будет сбрасываться в базу данных при каждом необработанном изменении из контекста - не только изменения, выполненные на этом конкретном этапе рекурсии. Это также требует TransactionScope если вы хотите сохранить все в одной атомной операции.
  6. Этот подход - отличный способ ввести проблемы с параллелизмом и еще хуже - взаимоблокировки к вашему приложению.
  7. Это зависит от EntityObject - OMG, почему книга о EF6 содержит код, связанный с классом EntityObject ? Похож на дойную корову с контентом, скопированным из старой версии об EF4. У меня нет ничего против ObjectContext API, кроме EntityObject ? В самом деле?

Короче говоря, сделайте себе одолжение и исправьте свою модель БД и сущности, если вы хотите, чтобы каскад удалял или не использовал каскадное удаление и вручную (предпочтительно с прямым SQL) удалять зависимости. Существует также возможность использовать триггеры для выполнения этого SQL, но я не рассматриваю триггеры как хороший вариант.




Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему
Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему