使用数据库拦截器的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) {...}
会使它运作
好吧,你的代码对我来说似乎很好。 也许有一点错误就是打破你的应用程序。 你可以试试这个:
-
从
BC_Instance
删除BC_Instance
-
编辑
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()); }); -
删除
ApplicationDbConfiguration
类 -
编辑上下文的构造函数
public ApplicationDbContext() : base("DefaultConnection", throwIfV1Schema: false) { DbInterception.Add(new SoftDeleteInterceptor()); }
希望这可以帮助!