Вы можете переписать метод SaveChangesAsync
в DbContext, чтобы обновить значение isDeleted
как в родительском, так и в дочернем объектах. Также не забудьте отключить каскадное удаление ядра EF.
См. Следующие шаги:
1.Модели:
public class Api
{
[Key]
public int ID { get; set; }
//other properties
public bool isDeleted { get; set; }
public List<ApiApplicant> ApiApplicants { get; set; }
}
public class ApiApplicant
{
[Key]
public int Id { get; set; }
public int? ApiID { get; set; }//set as nullable
//other properties
public bool isDeleted { get; set; }
[ForeignKey("ApiID")]
public Api Api { get; set; }
}
2.DbContext (отключить каскадное удаление по умолчанию)
public class ApplicationDbContext : IdentityDbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
public DbSet<Api> Apis { get; set; }
public DbSet<ApiApplicant> ApiApplicants { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Api>()
.HasMany(i => i.ApiApplicants)
.WithOne(c => c.Api)
.OnDelete(DeleteBehavior.Restrict);
}
public override int SaveChanges(bool acceptAllChangesOnSuccess)
{
OnBeforeSaving();
return base.SaveChanges(acceptAllChangesOnSuccess);
}
public override Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default(CancellationToken))
{
OnBeforeSaving();
return base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
}
private void OnBeforeSaving()
{
foreach (var entry in ChangeTracker.Entries())
{
if (entry.State == EntityState.Deleted)
{
if (entry.Entity is Api )
{
entry.State = EntityState.Modified;
//change Api.isDeleted value to true
entry.CurrentValues["isDeleted"] = true;
//change navigations' isDeleted value to true
foreach (var c in entry.Collections)
{
if(c.Metadata.Name == "ApiApplicants")
{
foreach (var item in (IEnumerable)c.CurrentValue)
{
((ApiApplicant)item).isDeleted = true;
}
}
}
}
}
}
}
}
3. Удалить действие
[HttpPost]
public async Task<IActionResult> DeleteConfirmed(int id)
{
var api = await _context.Apis.Include(a => a.ApiApplicants).FirstOrDefaultAsync(a=>a.ID == id);
_context.Apis.Remove(api);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}