Почему Entity Framework Soft Delete через SaveChanges? (И альтернативное решение)C#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Почему Entity Framework Soft Delete через SaveChanges? (И альтернативное решение)

Сообщение Anonymous »

Я хочу реализовать Soft Delete в моем приложении, что означает, что вместо физического удаления записей из базы данных я установил «Isdeleted» флаг на True. Мое ожидание состоит в том, чтобы перехватить процесс удаления в рамках сущности (EF), переопределяя SaveChanges, чтобы любая операция удаления удалялась в мягкое удаление. Когда объект помечается для удаления (EntityState.Deleted), EF рассчитывает выполнить жесткий удаление в базе данных. Переопределение SaveChanges и изменение состояния сущности на изменение (для обновления флага Isdeleted) работает для основного объекта, но не обрабатывает связанных объектов с каскадными отношениями удаления. Внутренний механизм удаления каскада EF тесно связан с твердыми удалениями и не запускает мягкие удаления. Это означает, что зависимые объекты не являются мягкими, как ожидалось. MEDEPERCASCASCADESOFTDELETE в моем APPDBCONTEXT. Этот метод вручную пересекает все навигационные свойства с помощью DeleteBehavior.Cascade, нагрузки, связанных с сущностями и рекурсивно отмечает их как мягкие удаленные путем установления своего флага иметрита и обновления их состояния. Это гарантирует, что когда на родительском объекте выполняется мягкое удаление, все зависимые объекты также мягко удаляются, имитируя поведение каскада удаления. < /P>
public int SaveChanges()
{
return _dbContext.SaveChanges();
}
< /code>
public override int SaveChanges()
{
PrepareEntites();
return base.SaveChanges();
}
< /code>
private void PrepareEntites()
{
List entities = ChangeTracker.Entries().ToList();

foreach (EntityEntry entity in entities)
{
switch (entity.State)
{
case EntityState.Deleted:
HandleSoftDelete(entity);
break;

case EntityState.Added:
HandleCreate(entity);
break;

case EntityState.Modified:
if (!Convert.ToBoolean(entity.Property(nameof(BaseEntity.IsDeleted)).CurrentValue))
{
HandleUpdate(entity);
}
break;
}
}
}
< /code>
private void HandleSoftDelete(EntityEntry entity)
{
entity.State = EntityState.Modified;
entity.Property(nameof(BaseEntity.IsDeleted)).CurrentValue = true;
entity.Property(nameof(BaseEntity.DeleteDate)).CurrentValue = DateTime.UtcNow;
SetUserId(entity.Entity, UserProperty.DeleteUserId);

RecursiveCascadeSoftDelete(entity.Entity);
}
< /code>
private void RecursiveCascadeSoftDelete(BaseEntity mainEntity)
{
IEntityType? entityType = this.Model.FindEntityType(mainEntity.GetType());
if (entityType == null)
return;

foreach (INavigation navigation in entityType.GetNavigations())
{
IForeignKey foreignKey = navigation.ForeignKey;
if (foreignKey.DeleteBehavior != DeleteBehavior.Cascade)
continue;

object? related = navigation.GetGetter().GetClrValue(mainEntity);
if (related == null)
{
EntityEntry entry = Entry(mainEntity);
if (navigation.IsCollection)
entry.Collection(navigation.Name).Load();
else
entry.Reference(navigation.Name).Load();

related = navigation.GetGetter().GetClrValue(mainEntity);
}

if (related is IEnumerable collection)
{
foreach (BaseEntity dependent in collection)
TrySoftDeleteAndRecurse(dependent);
}
else if (related is BaseEntity dependent)
{
TrySoftDeleteAndRecurse(dependent);
}
}
}
< /code>
private void TrySoftDeleteAndRecurse(BaseEntity dependent)
{
EntityEntry? dependentEntry = ChangeTracker.Entries()
.FirstOrDefault(e => e.Entity == dependent);
dependentEntry ??= Entry(dependent);
if (dependentEntry.State == EntityState.Unchanged || dependentEntry.State == EntityState.Detached)
{
dependentEntry.State = EntityState.Deleted;
}
if (dependentEntry.State != EntityState.Deleted)
return;

dependentEntry.State = EntityState.Modified;
dependentEntry.Property(nameof(BaseEntity.IsDeleted)).CurrentValue = true;
dependentEntry.Property(nameof(BaseEntity.DeleteDate)).CurrentValue = DateTime.UtcNow;
SetUserId(dependentEntry.Entity, UserProperty.DeleteUserId);

RecursiveCascadeSoftDelete(dependentEntry.Entity);
}


Подробнее здесь: https://stackoverflow.com/questions/797 ... ative-solu
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Почему Entity Framework Soft-Delete через Savechanges? (и альтернативное решение)
    Anonymous » » в форуме C#
    0 Ответы
    4 Просмотры
    Последнее сообщение Anonymous
  • JPA Soft Delete Repository + Auditing
    Anonymous » » в форуме JAVA
    0 Ответы
    3 Просмотры
    Последнее сообщение Anonymous
  • Update updated_by и updated_date на Soft Delete в Hibernate
    Anonymous » » в форуме JAVA
    0 Ответы
    7 Просмотры
    Последнее сообщение Anonymous
  • Причина возвращаемого значения 0 в SaveChanges() в Entity Framework
    Anonymous » » в форуме C#
    0 Ответы
    29 Просмотры
    Последнее сообщение Anonymous
  • WPF Datagrid не обновляется при вызове SaveChanges() в Entity Framework
    Anonymous » » в форуме C#
    0 Ответы
    27 Просмотры
    Последнее сообщение Anonymous

Вернуться в «C#»