EF Core 1.1 Soft(或逻辑)删除

时间:2017-11-17 14:36:08

标签: c# entity-framework entity-framework-core

我正在尝试在.NET Core 1.1。* Web App中实现Soft Delete,由Entity Framework Core 1.1支持。*。我正在使用Sql Server作为我的数据库。

迁移到.NET核心2. *目前不是一个选项。

在阅读书籍,图书和3d后,我使用Discriminator列实现了此功能。删除程序显然按预期工作。数据检索有什么问题:已删除的实体仍显示在我的EF查询结果中。

现状

这是一些C#代码。我会尽量简单的事情 接口:

// Soft deletion interface    
public intercace ISoftDeletable
{}

// Another interface for some shadow properties
public interface IEntity
{}

基类:

public abstract class Entity : IEntity, ISoftDeletable
{
   public int MyBaseProp { get; set; }
}

我的一个派生类:

public class MyDerivedEntity: Entity
{
   public string Name { get; set; }

   public IList<MyChildEntity> Children { get; set; }

}

public class MyChildEntity: Entity 
{
    public string MyChildProp { get; set; }
}

上下文

public class MyContext: DbContext
{
   public MyContext(DbContextOptions<MyContext> options)
            : base(options)
   { }

   public DbSet<MyDerivedEntity> EntitiesToUse { get; set; }

   protected override void OnModelCreating(ModelBuilder builder)
   {
      foreach (var entity in builder.Model.GetEntityTypes())
      {                
         if (typeof(IEntity).IsAssignableFrom(entity.ClrType))
         {
           builder.Entity(entity.ClrType).Property<string>("MyShadowProperty");
         }

         if (typeof(ISoftDeletable).IsAssignableFrom(entity.ClrType))
         {
            // Discriminator column
            builder.Entity(entity.ClrType).HasDiscriminator("IsDeleted", typeof(bool)).HasValue(false);
            // Shadow Property       
            builder.Entity(entity.ClrType).Property(typeof(bool), "IsDeleted").IsRequired(true).HasDefaultValue(false);

            builder.Entity(entity.ClrType).Property(typeof(bool), "IsDeleted").Metadata.IsReadOnlyAfterSave = false;
         }
      }

      // Other model configurations

      base.OnModelCreating(builder);
   }

   // SaveChangesAsync are almost the same
   public override int SaveChanges()
   {
       AuditEntities();

       return base.SaveChanges();
   }

   private void AuditEntities()
   {

      foreach (EntityEntry<IEntity> entry in ChangeTracker.Entries<IEntity>())
      {
         // do something with MyShadowProperty...
      }
      foreach (EntityEntry<ISoftDeletable> entry in changeTracker.Entries<ISoftDeletable>().Where(w => w.State == EntityState.Deleted))
      {
        // Set the entity as Softly Deleted
        entry.Property("IsDeleted").CurrentValue = true;
        // Ensure the entity state is modified to prevend hard deletion
        entry.State = EntityState.Modified;
      }
   }
}

问题

除数据检索外,一切都按预期工作。 这是一个示例电话:

var results = await _context.EntitiesToUse.Include(e => e.SomeChildEntity).AsNoTracking();

我希望结果只包含可用的 myDerivedEntities .IsDeleted == false。问题是我的已删除实体未被过滤掉。为什么呢?
请问,我的代码出了什么问题?我错过了什么吗?

非常感谢你们!

1 个答案:

答案 0 :(得分:2)

Entity Framework Core 2.0支持全局查询过滤器

Area 3

您可以找到更多信息和示例here

我建议您使用内置的EF Core全局查询过滤器,但在某些情况下,Entity Framework Plus也可以提供帮助。

免责声明:我是该项目的所有者

EF +查询过滤器允许您按全局和实例过滤DbSet。

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<ISoftDeletable>().HasQueryFilter(e => !e.IsDeleted);

    base.OnModelCreating(modelBuilder);
}

维基:EF+ Query Filter

编辑:回答子问题

  

请您的库与EF Core 1.1兼容

是的,它应该与.NET Standard 1.3兼容