如何将 DbModelBuilder 与数据库优先方法结合使用来实现软删除

How to use DbModelBuilder with Database First Approach to implement Soft Delete

提问人:rd53hu 提问时间:11/19/2015 更新时间:12/28/2022 访问量:1626

问:

我正在尝试在我们的 EF 6 项目中实现软删除。我们正在使用数据库优先的方法,我注意到您无法覆盖 .OnModelCreating

使用 Code-First 方法时,可以对特定实体应用全局筛选器,如本博客文章中所述。

如何使用数据库优先方法重新创建它?

public class MyContext : DbContext
{
    public virtual IDbSet<Company> Companies { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Company>()
            .Map(m => m.Requires("IsDeleted").HasValue(false))
            .Ignore(m => m.IsDeleted);
    }
}
C# sql-server asp.net-mvc 实体框架

评论

2赞 seagulledge 6/9/2017
解决方法是使用 SQL 视图筛选出软删除的记录。然后使用视图作为数据库优先模型。

答:

0赞 Shahzad Khan 5/29/2019 #1
public class MyContext : DbContext
{
    public virtual IDbSet<Company> Companies { get; set; }

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

        base.OnModelCreating(modelBuilder);
    }
}

你需要写基础。OnModelCreating(模型生成器);建立你的查询,我也在帖子中突出显示了行。

0赞 Agbon 7/1/2022 #2

在执行操作之前,需要以以下形式定义构造函数:

public MyContext(DbContextOptions<MyContext> options) : base(options)
    {

    }
    public virtual DbSet<Company> Companies { get; set; }

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

        base.OnModelCreating(modelBuilder);
    }
0赞 Yunus Kıran 12/28/2022 #3

如果使用数据库优先方法,则无需为 IsDeleted 标志添加 OnModelCreating 标志。在编写自定义 SaveChanges 方法时,可以进行处理。别忘了 ChangeTracker 必须处于打开状态。

例如;

public int SaveChanges(){
    var changeSet = ChangeTracker.Entries();
    foreach (var entry in changeSet.Where(c => c.State == System.Data.Entity.EntityState.Added)){
        var info = entry.Entity.GetType()
                    .GetProperty("IsDeleted", BindingFlags.Public | BindingFlags.Instance);
if ( info!=null && info.CanWrite){
    info.SetValue(entry.Entity, false, null);
}
}
base.SaveChanges();

}
1赞 jepozdemir 12/2/2023 #4

标准化软删除实体的最佳方法,下面将逐步介绍。

1-创建 ISoftDelete 接口:

public interface ISoftDelete
{
    bool IsDeleted { get; set; }
}

阿拉伯数字-然后创建要实现软删除方法的实体。

public class Company : ISoftDelete
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public long CompanyId { get; set; }
    public string Name { get; set; }
    public bool IsDeleted { get; set; }
}

3-通过重写 DBContext.SaveChanges() 方法将实体的状态从“已删除”更改为“已修改”,如下所示。

public override int SaveChanges()
{
    foreach (var entry in ChangeTracker.Entries().Where(p => p.State == EntityState.Deleted))
        TryCancelDeletion(entry);

    return base.SaveChanges();
}

private bool TryCancelDeletion(EntityEntry entry)
{
    if (!(entry.Entity is ISoftDelete))
        return false;

    entry.Reload();
    entry.State = EntityState.Modified;
    ((ISoftDelete)entry.Entity).IsDeleted = true;
    return true;
}

软删除实体实际上不会被删除,在数据库中标记为 IsDeleted = true,但无法正常检索到应用程序。

应应用默认筛选器,以便从结果中排除软删除的实体。