Entity Framework 6 暂时禁用拦截 [英] Entity Framework 6 Disable Interception temporarily

查看:14
本文介绍了Entity Framework 6 暂时禁用拦截的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 IDbCommandTreeInterceptor 在我的模型上启用软删除.

I am using an IDbCommandTreeInterceptor to enable soft deletes on my model.

System.Data.Entity.Infrastructure.Interception.DbInterception.Add(
     new SoftDeleteInterception());

我希望能够暂时禁用拦截器,以便我可以选择一个已删除"的实体进行审计.

I want to be able to disable the interceptor temporarily so that I can select a "deleted" entity for auditing purposes.

但是,DbInterception 集合似乎是程序集范围的.

However, It seems like the DbInterception collection is assembly-wide.

有没有什么方法可以创建一个新的DbContext 没有 拦截?甚至是每次创建时将拦截器添加到 DbContext 的方法?

Is there any way to create a new DbContext without interception on? Or even a way to add the interceptor to the DbContext every time it is created?

推荐答案

我扩展了我的数据库上下文类,增加了属性

I have extended my db context class with additional property

[DbConfigurationType(typeof(DbConfig))] 
public partial class YourEntitiesDB 
{
    public bool IgnoreSoftDelete { get; set; }
}

然后在 TreeCreated(...) 方法中检查此标志,如果为 true,则它不会进一步进入 QueryVisitor

Then in the TreeCreated(...) method i check this flag and if true then it just doesn't go further to the 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

In order to use it i just set the flag to true when needed

YuorEntitiesDB DB = new YuorEntitiesDB();
DB.IgnoreSoftDelete = true;
DB.Records.Where(...)

这篇关于Entity Framework 6 暂时禁用拦截的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆