【问题标题】:How to use the interception mechanism in Entity Framework 6.3?Entity Framework 6.3中如何使用拦截机制?
【发布时间】:2017-04-06 04:30:29
【问题描述】:

我们需要在我们的应用程序中添加一个新功能,例如对于我们的 DbContext 在其 DbSets 上执行的 SELECT 查询,例如在调用 MyDbContext.Users 或 MyDbContext.Students 等时(User 和 Student 继承自 BaseEntity 类,其中包括一个属性 IsActive),我们将能够拦截它们,检查实体是否属于此基本类型 BaseEntity,并以某种方式修改查询,例如添加 where 子句来检查 IsActive 是否为真。我试图研究 IDbCommandInterceptor 接口,但它的方法,包括可能与我相关的方法,ReaderExecuting,拦截在数据库上执行的各种 SELECT 语句,而不仅仅是 MyDbContext 的数据库集。
我怎样才能以正确的方式做到这一点?

谢谢,阿希隆

【问题讨论】:

    标签: c# entity-framework-6


    【解决方案1】:

    在这种情况下,拦截器可能不是您想要的。它们拦截所有 DbContexts 的所有查询,您只能直接修改 SQL。当您想要添加 where 子句时,这太危险了,因为连接可能会搞砸一切。

    如果您有一个存储库或某个基类,所有查询都会通过,请在此处进行。如果你总是在做 context.Students.Where(...) 那么你可以做一件偷偷摸摸的事情,但不完全确定这是否可行,但我不明白为什么它不会。

    在您的 DbContext 类上,我会将所有命名为 Student 的 DbSet 属性更改为 StudentDbSet。然后我会添加这个属性来替换它:

    public IQueryable<Student> Students 
    { 
        get { return StudentdsDbSet.Where(a => a.IsActive); }
    }
    

    所有旧代码现在都将引用这个强制 IsActive 仅记录的属性。然后,如果您需要非活跃的学生,您可以执行 StudentsDbSet.Where(...) ,您就可以开始了。

    【讨论】:

    • 优秀的答案丹尼尔!很好的解释和很好的解决方法。只是一个小问题:您返回 IQueryable 而不是 DbSet 是否有原因? StudentsDbSet 是否也需要是 IQueryable 的?非常感谢。
    • 当您执行 Where 子句时,这将是 IQueryable。它不再返回 DbSet。您需要 Context 上的 DbSet 属性,因为我相信 Entity Framework 就是这样知道如何连接映射的。
    猜你喜欢
    • 2017-02-01
    • 1970-01-01
    • 2019-07-07
    • 2015-03-15
    • 2014-09-30
    • 1970-01-01
    • 2017-11-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多