EF6, сначала DB, мягкое удаление - отображение условий вычисляемого столбца

Я хотел бы реализовать функцию мягкого удаления в приложении, которое использует EF6 с подходом базы данных вначале (.edmx). Следующие советы и рекомендации из ссылок: link1 и link2 Мне удалось сделать следующее:

  • Добавлен столбец IsDeleted на столе
  • Добавлен вычисляемый столбец IsDeletedMapping для таблицы, который имеет то же значение, что и IsDeleted
  • Добавлен интерфейс ISoftDelete, который будет реализован на объектах таблиц

Затем я добавил код для обработки действия Delete для сущностей в моем методе SqlRepository Delete.

// if has ISoftDelete interface perform soft delete.
if (typeof (ISoftDelete).IsAssignableFrom(typeof (T)))
{
     entry.State = EntityState.Modified;
     var tempEntry = entry.Entity as ISoftDelete;
     tempEntry.IsDeleted = true;
}
// else, mark entity state as Deleted
else
{
     entry.State = EntityState.Deleted;
}

Это означает, что сущности, которые реализуют интерфейс ISoftDelete, будут вместо удаления в БД просто обновляться с помощью IsDeleted = true. Также IsDeletedMapping будет установлен в true, так как он рассчитывается из IsDeleted.

Проблема, с которой я сейчас сталкиваюсь, состоит в том, как отфильтровать IsDeleted = false в запросах EF.

Я попытался сопоставить условие на IsDeletedMapping, так как это означает, что EF автоматически отфильтрует это для нас.

Отображение условий IsDeletedMapping

Но здесь кроется проблема. IsDeletedMapping имеет свойство StoreGeneratedPattern, установленное в Computed, и поэтому я получаю ошибку:

Ошибка 2016: Невозможно указать условие для члена столбца "IsDeletedMapping", поскольку он помечен с помощью "Computed" или "Identity" StoreGeneratedPattern.

Таким образом, вопрос заключается в следующем: есть ли обходной путь для установки сопоставления условий в вычисляемом столбце? Кроме того, если у вас есть какой-то лучший подход к реализации мягкого удаления, я буду более чем счастлив попробовать. Имейте в виду, что реализация должна автоматически фильтровать удаленные записи.

Спасибо за ваши ответы!

1 ответ

Я думаю, что ваша реализация слишком сложна. Вот что мы сделали:

  1. Добавьте столбец IsDeleted (bool, not null) в таблицы
  2. Сопоставить функцию удаления объекта с хранимой процедурой, которая фактически устанавливает IsDeleted = 0вместо реального удаления. Это также заставит вас отобразить функции Вставка и Обновление, но мы все равно предпочли процедуры.
  3. Отфильтруйте объект по IsDeleted = 0 в edmx

Теперь все ваши объекты автоматически фильтруются IsDeleted = 0и ваш метод Delete в репозитории может сделать реальное удаление, скрывая тот факт, что записи на самом деле не удаляются из базы данных. Так что, если вы когда-нибудь захотите сделать реальное удаление или, возможно, сделать мягкое удаление только для некоторых объектов, ваш код об этом не узнает.

Не забывайте, что если поле таблицы является фильтром сущностей, оно не может быть сопоставлено со свойством сущности. Ваш код не будет иметь свойства IsDeleted в классе сущности.

Другие вопросы по тегам