EF6, БД сначала, обратимое удаление - сопоставление условий вычисляемого столбца

Я хотел бы реализовать функцию мягкого удаления в приложении, использующем EF6 с подходом базы данных в первую очередь (.edmx). Следуя советам и рекомендациям по ссылкам: true-usin">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», так как он помечен StoreGeneratedPattern «Computed» или «Identity».

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

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


person nymeron    schedule 18.12.2015    source источник
comment
Я настоятельно рекомендую удалить эту логику из сущностей, которые вы сопоставляете с БД, и сохранить ее на уровне DAO - переопределить операцию репозитория. Удалить или что-то в этом роде. Судя по моему опыту, возиться с вычисляемыми свойствами в EF довольно рискованно и бесполезно.   -  person Red    schedule 18.12.2015


Ответы (1)


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

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

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

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

person Tsahi Asher    schedule 03.05.2016