Entity Framework 6 暂时禁用拦截
Entity Framework 6 Disable Interception temporarily
我正在使用 IDbCommandTreeInterceptor
在我的模型上启用软删除。
System.Data.Entity.Infrastructure.Interception.DbInterception.Add(
new SoftDeleteInterception());
我希望能够暂时禁用拦截器,以便我可以 select 一个 "deleted" 实体用于审计目的。
但是,DbInterception
集合似乎是全程序集。
有什么方法可以创建一个新的 DbContext
而无需 拦截?
或者甚至是在每次创建时将拦截器添加到 DbContext
的方法?
我已经用额外的 属性
扩展了我的数据库上下文 class
[DbConfigurationType(typeof(DbConfig))]
public partial class YourEntitiesDB
{
public bool IgnoreSoftDelete { get; set; }
}
然后在 TreeCreated(...) 方法中我检查这个标志,如果为真那么它就不会进一步到 QueryVisitor
public class SoftDeleteInterceptor : IDbCommandTreeInterceptor
{
public SoftDeleteInterceptor()
{
}
public void TreeCreated(DbCommandTreeInterceptionContext interceptionContext)
{
var db = interceptionContext.DbContexts.FirstOrDefault() as YourEntitiesDB;
if (db!=null && db.IgnoreSoftDelete)
{
// Ignore soft delete interseptor (Used in archives)
return;
}
if (interceptionContext.OriginalResult.DataSpace == DataSpace.CSpace)
{
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<DbModificationClause>();
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;
}
}
}
}
}
为了使用它,我只是在需要时将标志设置为 true
YuorEntitiesDB DB = new YuorEntitiesDB();
DB.IgnoreSoftDelete = true;
DB.Records.Where(...)
我正在使用 IDbCommandTreeInterceptor
在我的模型上启用软删除。
System.Data.Entity.Infrastructure.Interception.DbInterception.Add(
new SoftDeleteInterception());
我希望能够暂时禁用拦截器,以便我可以 select 一个 "deleted" 实体用于审计目的。
但是,DbInterception
集合似乎是全程序集。
有什么方法可以创建一个新的 DbContext
而无需 拦截?
或者甚至是在每次创建时将拦截器添加到 DbContext
的方法?
我已经用额外的 属性
扩展了我的数据库上下文 class[DbConfigurationType(typeof(DbConfig))]
public partial class YourEntitiesDB
{
public bool IgnoreSoftDelete { get; set; }
}
然后在 TreeCreated(...) 方法中我检查这个标志,如果为真那么它就不会进一步到 QueryVisitor
public class SoftDeleteInterceptor : IDbCommandTreeInterceptor
{
public SoftDeleteInterceptor()
{
}
public void TreeCreated(DbCommandTreeInterceptionContext interceptionContext)
{
var db = interceptionContext.DbContexts.FirstOrDefault() as YourEntitiesDB;
if (db!=null && db.IgnoreSoftDelete)
{
// Ignore soft delete interseptor (Used in archives)
return;
}
if (interceptionContext.OriginalResult.DataSpace == DataSpace.CSpace)
{
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<DbModificationClause>();
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;
}
}
}
}
}
为了使用它,我只是在需要时将标志设置为 true
YuorEntitiesDB DB = new YuorEntitiesDB();
DB.IgnoreSoftDelete = true;
DB.Records.Where(...)