Soft Delete the childs of my entity

c# entity-framework-core


  • I have a sample with sampleItems.
  • I delete a sampleItem from the list of sampleItems in sample.
  • I save the DBContext.

I want to SoftDelete the sampleItem.

My code:

public class Entity: {
        public Guid Id { get; set; }
        public bool IsDeleted { get; set; }

public class Sample : Entity{
        public string Text { get; set; }
        public List<SampleItem> SampleItems { get; set; } = new List<SampleItem>();

public class SampleItem :Entity{
        public string Text { get; set; }
        public virtual Sample Sample { get; set; }

When I get the entity from the DB:

var sample = context.Samples.First(s=>s.Id == myId);

In MyDbContext I have:

public override Task<int> SaveChangesAsync(CancellationToken cancellationToken = default(CancellationToken))
    foreach (var entry in ChangeTracker.Entries())
        switch (entry.State)
            case EntityState.Added:
                //Do stuff

            case EntityState.Modified:
                //Do stuff

            case EntityState.Deleted:
                if (entry.Entity is Entity entity)
                    entry.State = EntityState.Unchanged;
                    entity.IsDeleted = true;

    return base.SaveChangesAsync(cancellationToken);

So I expected to have the SampleItem I deleted with an entryState to Deleted, but not, the entryState is set to Modified. But When I look in the database after operations done, the sampleItem is deleted.

How can I softDelete the sampleItem in this situation?


I read here:, the answer from ajcvickers that I could use "entry.Navigations".

I notice that SampleItem has NavigationEntries, all SampleItems are in it except the one I deleted.

So maybe we can imagine a linq function to the one who are not in the list? I m trying with no success currently. Is there someone who knows how to do it?

        var x = ChangeTracker.Entries()
            .Where(e => !e.Navigations
                .Where(n => !n.Metadata.IsDependentToPrincipal())
                .Where(n => n is CollectionEntry)
                .Select(n => n as CollectionEntry)
                .SelectMany(n => n.CurrentValue.Cast<object>())


Here:, I found a way to disabled Cascade delete.

foreach (var relationship in modelBuilder.Model.GetEntityTypes().SelectMany(e => e.GetForeignKeys()))
    relationship.DeleteBehavior = DeleteBehavior.Restrict;

Now I have an error when I execute the SaveChanges:

"The association between entities 'Sample' and 'SampleItem' with the key value '{Id: 1c41c336-b75b-4f6b-6057-08d5f3d981ae}' has been severed but the relationship is either marked as 'Required' or is implicitly required because the foreign key is not nullable. If the dependent/child entity should be deleted when a required relationship is severed, then setup the relationship to use cascade deletes."

(more details about Cascade configuration:

Which is normal. Now I need to find to disable the delete of the SampleItem and enable the SoftDelete.

Do you have an idea?

7/28/2018 3:02:46 AM

Popular Answer

You are probably solved this already BUT remove the sample.SampleItems.RemoveAt(index); and replace with:

// Do the soft delete
db.IsSoftDelete = true;
db.Entry(activity).State = EntityState.Modified;

db.UserId = userId;
await db.SaveChangesAsync();

Then on your Override SaveChanges:

public bool IsSoftDelete { get; set; }

public override int SaveChanges()
// Modified State
                var modified = this.ChangeTracker.Entries()
                            .Where(t => t.State == EntityState.Modified)
                            .Select(t => t.Entity)

                foreach (var entity in modified)
                    if (entity is ITrack)
                        var track = entity as ITrack;
                        Entry(track).Property(x => x.CreatedDate).IsModified = false;
                        Entry(track).Property(x => x.CreatedBy).IsModified = false;
                        track.ModifiedDate = DateTime.UtcNow;
                        track.ModifiedBy = UserId;

                        if (IsSoftDelete)
                            track.IsDeleted = true;
                            track.DeletedDate = DateTime.UtcNow;
                            track.DeletedBy = UserId;
9/22/2019 5:09:46 AM

Related Questions


Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow