使用数据库拦截器的entity framework软删除实现不起作用

我使用以下教程实现了一个数据库软删除(一个将条目标记为已删除的布尔标志): http : //www.codeguru.com/csharp/csharp/soft-deleting-entities-cleanly-using-entity-framework- 6- interceptors.html

在我看来,这是一个非常好的实现,因为一旦设置了软删除就可以通过添加[SoftDelete("IsDeleted")]注释来应用于模型。 问题到目前为止它无法正常工作。

来源似乎是可靠的,他们甚至发布了他们的解决方案的一个例子: https : //github.com/rakeshbabuparuchuri/EFExpensionPoints

在将软删除应用到我的项目中时,如果我做错了什么,你能看看我的代码吗?

这是模型:

 [SoftDelete("IsDeleted")] public class BC_Instance { public int ID { get; set; } public bool IsDeleted { get; set; } } 

ApplicationDbContext.cs:

 namespace bcplatform2.Models { public class ApplicationDbContext : IdentityDbContext { public ApplicationDbContext() : base("DefaultConnection", throwIfV1Schema: false) { } // Add a DbSet for each one of your Entities //public DbSet VirtualGuests { get; set; } public DbSet BiocloudInstances { get; set; } static ApplicationDbContext() { Database.SetInitializer(new ApplicationDbInitializer()); } public static ApplicationDbContext Create() { return new ApplicationDbContext(); } protected new void OnModelCreating(DbModelBuilder modelBuilder) { var conv = new AttributeToTableAnnotationConvention( "SoftDeleteColumnName", (type, attributes) => attributes.Single().ColumnName); modelBuilder.Conventions.Add(conv); } } } 

ApplicationDbConfiguration.cs

 namespace bcplatform2.DAL { public class ApplicationDbConfiguration : DbConfiguration { public ApplicationDbConfiguration() { AddInterceptor(new SoftDeleteInterceptor()); } } } 

SoftDeleteAttribute.cs:

 namespace bcplatform2.Helpers { public class SoftDeleteAttribute : Attribute { public SoftDeleteAttribute(string column) { ColumnName = column; } public string ColumnName { get; set; } public static string GetSoftDeleteColumnName(EdmType type) { MetadataProperty annotation = type.MetadataProperties .Where(p => p.Name.EndsWith("customannotation:SoftDeleteColumnName")) .SingleOrDefault(); return annotation == null ? null : (string)annotation.Value; } } } 

SoftDeleteInterceptor.cs

我注意到SoftDeleteAttribute.GetSoftDeleteColumnName(deleteCommand.Target.VariableType.EdmType)找不到软删除属性并返回null。 但我不知道为什么。

 namespace bcplatform2.Helpers { public class SoftDeleteInterceptor : IDbCommandTreeInterceptor { public void TreeCreated(DbCommandTreeInterceptionContext interceptionContext) { if (interceptionContext.OriginalResult.DataSpace == DataSpace.SSpace) { var queryCommand = interceptionContext.Result as DbQueryCommandTree; if (queryCommand != null) { var newQuery = queryCommand.Query.Accept(new SoftDeleteQueryVisitor()); interceptionContext.Result = new DbQueryCommandTree( queryCommand.MetadataWorkspace, queryCommand.DataSpace, newQuery); } var deleteCommand = interceptionContext.OriginalResult as DbDeleteCommandTree; if (deleteCommand != null) { var column = SoftDeleteAttribute.GetSoftDeleteColumnName(deleteCommand.Target.VariableType.EdmType); if (column != null) { var setClauses = new List(); var table = (EntityType)deleteCommand.Target.VariableType.EdmType; if (table.Properties.Any(p => p.Name == column)) { setClauses.Add(DbExpressionBuilder.SetClause( DbExpressionBuilder.Property( DbExpressionBuilder.Variable(deleteCommand.Target.VariableType, deleteCommand.Target.VariableName), column), DbExpression.FromBoolean(true))); } var update = new DbUpdateCommandTree( deleteCommand.MetadataWorkspace, deleteCommand.DataSpace, deleteCommand.Target, deleteCommand.Predicate, setClauses.AsReadOnly(), null); interceptionContext.Result = update; } } } } } } 

IdentityConfig.cs

 public class ApplicationDbInitializer : DropCreateDatabaseIfModelChanges { protected override void Seed(ApplicationDbContext context) { InitializeIdentityForEF(context); base.Seed(context); } //Create User=Admin@Admin.com with password=Admin@123456 in the Admin role public static void InitializeIdentityForEF(ApplicationDbContext db) { //Initialize users and roles... } } 

ApplicationDbContext.cs中存在一个错误:

 protected new void OnModelCreating(DbModelBuilder modelBuilder) {...} 

您正在使用“new”而不是“override”,因此永远不会执行OnModelCreating(尝试添加断点来检查它)。 因此,AttributeToTableAnnotationConvention永远不会运行,并且永远不会添加实体注释。

将其更改为

 protected override void OnModelCreating(DbModelBuilder modelBuilder) {...} 

会使它运作

好吧,你的代码对我来说似乎很好。 也许有一点错误就是打破你的应用程序。 你可以试试这个:

  1. BC_Instance删除BC_Instance

  2. 编辑OnModelCreating方法

     AttributeToTableAnnotationConvention conv = new AttributeToTableAnnotationConvention( "SoftDeleteColumnName", (type, attributes) => attributes.Single().ColumnName); modelBuilder.Conventions.Add(conv); //this will dynamically add the attribute to all models modelBuilder.Types().Configure(delegate(ConventionTypeConfiguration i) { i.HasTableAnnotation("SoftDeleteColumnName", Entity.G etSoftDeleteColumnName()); }); 
  3. 删除ApplicationDbConfiguration

  4. 编辑上下文的构造函数

     public ApplicationDbContext() : base("DefaultConnection", throwIfV1Schema: false) { DbInterception.Add(new SoftDeleteInterceptor()); } 

希望这可以帮助!