3

I'm using entity framework and in my context I've done some stuff like:

public override int SaveChanges()
{
    foreach (var entry in ChangeTracker.Entries())
    {
        if (entry.Entity is Base entity)
        {
            if (entry.State == EntityState.Added)
            {
                entity.Created = DateTime.UtcNow;
                entity.Modified = DateTime.UtcNow;
            }
            else if (entry.State == EntityState.Modified)
            {
                entity.Modified = DateTime.UtcNow;
            }
        }
    }
    return base.SaveChanges();
}

Where Base is:

    public int Id { get; set; }
    public DateTime? Created { get; set; }
    public DateTime? Modified { get; set; }
    public bool IsDeleted { get; set; }

Now what I'm trying to do is when I load properties using my context like:

_context.MyEntities.AsEnumerable(something);

I want it to select all entities that have the IsDeleted property set to false. Is it possible to do this in the DbContext like I'm making changes by overriding SaveChanges()

I can see that there is a method to override, but not sure how to go about it:

public override DbSet<TEntity> Set<TEntity>()
{
    return base.Set<TEntity>();
}
Daniil Grankin
  • 3,841
  • 2
  • 29
  • 39
px06
  • 2,256
  • 1
  • 27
  • 47
  • Are you looking for `_context.MyEntities.Where(x => !x.IsDeleted).ToList()`? Calling `.AsEnumerable()` will download the entire table into memory, beware. – Camilo Terevinto Dec 07 '17 at 22:36
  • @CamiloTerevinto No, I don't want to do it like that because it would require me to check for the deleted flag each time I want to load entities. I was wondering if there's a way to exclude the deleted entities on a more lower level using the context object. – px06 Dec 07 '17 at 22:37
  • What version of EF? You can handle soft deletes transparently in 6+ and Core 2+ – Aluan Haddad Dec 07 '17 at 22:44
  • @AluanHaddad Indeed using EF6 and MVC5. – px06 Dec 07 '17 at 22:45
  • @px06 if you want soft deletes, watch [this presentation by Rowan Miller](https://channel9.msdn.com/Events/TechEd/NorthAmerica/2014/DEV-B417). See ~11 minutes in for soft deletes. – Aluan Haddad Dec 07 '17 at 22:47

1 Answers1

2

If I understand you correctly you need to add something like this in DbContext

public DbSet<MyEntity> ExistingMyEntities {
    get { return MyEntities.Where(x => !x.IsDeleted); }
}

So then as you want you can use context object to retrieve not deleted entities.

UPDATE

Also you can filter by IsDeleted with model builder (if there is used soft delete How can I automatically filter out soft deleted entities with Entity Framework?)

public class MyContext : DbContext
{
    public virtual IDbSet<MyEntity> MyEntities { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<MyEntities>()
            .Map(m => m.Requires("IsDeleted")).HasValue(false).Ignore(m => m.IsDeleted);
    }
}

I was misinformed with Ignore, but as Jan Muncinsky noticed there can be used HasValue method for filtering.

Daniil Grankin
  • 3,841
  • 2
  • 29
  • 39
  • 1
    `Ignore(m => m.IsDeleted)` does not filter anything, it will just ignore property during mapping. – Jan Muncinsky Dec 08 '17 at 10:00
  • @JanMuncinsky probably you are right, I've read somewhere it filters... I'm trying to find it. – Daniil Grankin Dec 08 '17 at 10:02
  • https://putshello.wordpress.com/2014/08/20/entity-framework-soft-deletes-are-easy/ – Daniil Grankin Dec 08 '17 at 10:03
  • you could filter them by: `modelBuilder.Entity().Map(m => m.Requires("IsDeleted").HasValue(false))`. But it would require to drop `IsDeleted` out of the model and leave it in only in DB, so it's not useful in this case. – Jan Muncinsky Dec 08 '17 at 10:06
  • @JanMuncinsky it's not necessary should be out of the model. But there is no a reason to have it in model, value of the property will be false for all retrieved entities. – Daniil Grankin Dec 08 '17 at 10:12
  • Not sure about this. I would guess that deleting is performed just by setting `IsDeleted` to true and than calling 'SaveChanges' on context, but in this case `IsDeleted` is stripped out of mapping, so it wouldn't save anything. – Jan Muncinsky Dec 08 '17 at 10:17
  • @JanMuncinsky I suppose there is used soft delete another way than through the property https://stackoverflow.com/questions/12698793/how-can-i-automatically-filter-out-soft-deleted-entities-with-entity-framework – Daniil Grankin Dec 08 '17 at 10:19