EF6 Disable Query Plan Caching with Command Tree Interceptor

后端 未结 4 1950
执笔经年
执笔经年 2021-02-18 14:28

I\'m using IDbCommandTreeInterceptor to implement soft-delete functionality. Inside standard TreeCreated method I check whether given query command con

4条回答
  •  伪装坚强ぢ
    2021-02-18 14:39

    I know this question was asked some time ago, but since no post was marked as answer i share my recent experiences with that issue. As Dave correctly explained "It's important to distinguish between Query Plan Caching and Result Caching". Here the problem is Query Plan Caching, because

    A Query Cache is an optimized SQL instruction plan. These plans help make EF queries faster than "Cold" Queries. These Plans are cached beyond and particular context.

    So even if you create a new context, the problem remains, because the interceptor is not applied to "Query Plan cached" queries. My solution to this is very simple. Instead of relying only on the Interceptor, we can add a Where clause to the query in case of ShouldFetchSoftDeleted = true. With that EF uses another query and does not reuse the wrongly cached one. The interceptor now will be called but ShouldFetchSoftDeleted = true prevents your QueryVisitor to apply the IsDeleted filter.

    I'm using a Repository pattern, but I think the concept is clear.

    public override IQueryable Find()
    {
       var query = GetRepository().Find();
    
       if (!ShouldFetchSoftDeleted)
       {
         return query; // interceptor handles soft delete
       }
    
       query = GetRepository().Find();
       return Where(query, x => x.IsDeleted == false || x.IsDeleted);
    }
    

提交回复
热议问题