Entity Framework — Обратная проверка внешнего ключа

#entity-framework #reflection #foreign-keys #entity #foreign-key-relationship

#entity-framework #отражение #внешние ключи #сущность #foreign-key-relationship

Вопрос:

У нас есть система, которая позволяет администраторам создавать новые типы контента в системе, включая ссылки по внешнему ключу на другие таблицы. Затем администратор может перестроить базу данных, после чего он создает таблицы и все необходимые связи, затем перестраивает EDMX и все перекомпилирует. Работает как чемпион (я этого не писал, иначе я мог бы знать ответ на этот вопрос).

Один из недостатков, с которым мы сталкиваемся, заключается в том, что пользователь переходит к удалению записи, на которую может быть связан элемент в другой таблице. Это выдает ошибку из-за ссылочной целостности. Я, конечно, улавливаю это, но все, что я могу предоставить прямо сейчас, это тип ошибки типа «Вы не можете удалить этот элемент, потому что он связан с чем-то». Я бы предпочел проверить, можно ли удалить элемент, и отключить кнопку, если нет.

Есть ли способ, которым я могу определить, с какой таблицей / строкой связан элемент, подлежащий удалению, во время выполнения? Обычно я бы просто запрашивал связанные таблицы, но из-за особенностей этого приложения я не знаю, какими были бы эти другие таблицы во время разработки.

Короче говоря, если у меня есть:

Foo: fooId, FooName Строка: BarID, fooId, BarName Pow: PowID, fooId, PowName

Возможно ли определить во время выполнения, что строка в Foo не может быть удалена из-за привязки FK либо из Bar, либо из Pow, и, если да, могу ли я затем определить, какая таблица вызывает ошибку?

Заранее спасибо; первая публикация здесь, поэтому, пожалуйста, извините за любые ошибки в этикете :).

Ответ №1:

Вы должны запросить метаданные и получить список всех свойств навигации

 ObjectSet = context.CreateObjectSet<YourEntityType>();

// Get entity set for current entity type
var entitySet = ObjectSet.EntitySet;
// Get name of the entity's navigation properties
_propertyNames = ((EntityType)entitySet.ElementType).NavigationProperties.Select(p => p.Name).ToArray();
  

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

Я должен сказать, что архитектура вашего приложения ужасна. Это как пример: где не следует использовать EF или как не следует использовать EF.

Комментарии:

1. Что-нибудь конкретное из моего очень беглого описания и составленных таблиц, что заставляет вас так говорить («ужасная» часть)?

2. Да, я сталкиваюсь с ответами Ладислава здесь и там, и они обычно очень высокого качества, но я тоже удивлен этой частью «ужасной архитектуры». @Ladislav: не могли бы вы, пожалуйста, немного расширить это, поскольку не очевидно, что вы имеете в виду?

3. @zespri, @Chris: Если вы используете EF, вы определяете модель, вы определяете базу данных и вы пишете код, который использует вашу модель, вы тестируете приложение и развертываете его. Любое изменение модели зависит от разработчиков, которые должны убедиться, что приложение по-прежнему работает и что изменение не нарушает ни один из вариантов использования. Очевидно, что подход, описанный в вопросе, где администратор может запустить некоторую автоматическую потрясающую функцию, которая изменяет модель, восстанавливает классы, перестраивает сборки и повторно развертывает приложение, нарушает это довольно сильно. Я даже не понимаю, зачем вы это делаете, как вы можете использовать неизвестную функцию?

4. @Ladislav: Я слежу за тобой. По правде говоря, в этом гораздо больше, чем я описал, но я пытался не делать огромный пост. Приложение представляет собой CMS, и создаваемые таблицы преимущественно используют модель наследования таблиц по типу базового типа контента. Система использует динамические данные для всех операций CRUD, а инструмент администрирования (в нашем случае администраторы в значительной степени являются командой разработчиков) имеет в себе средства защиты для предотвращения изменения основных / обязательных полей и т.д.

5. @Chris: Хорошо, динамические данные — теперь это имеет гораздо больше смысла.