如何在实体框架中禁用每个查询的查询执行计划缓存?

时间:2015-07-02 06:12:19

标签: asp.net sql-server entity-framework

是否有机会使用实体框架禁用查询执行计划缓存?

我知道在objectQuery中我可以为每个查询禁用它:https://msdn.microsoft.com/pl-pl/library/system.data.objects.objectquery.enableplancaching(v=vs.110).aspx) 但我没有在dbQuery中看到这样的选项。

我也知道EF 6中有拦截器,我可以简单地附加选项(重新编译),但我找不到解决方法如何将它仅附加到一个完全查询而不是上下文中的每个查询。

1 个答案:

答案 0 :(得分:0)

Entity Framework's 6's `ObjectQuery.EnablePlanCaching` - where is it?的启发,我曾经这样写过:

    var optimizedQuery = DisablePlanCaching(query).AsNoTracking();

使用这些扩展方法:

    public static IQueryable<T> DisablePlanCaching<T>(IQueryable<T> query)
    {
        var objectQuery = GetObjectQuery(query);
        if (objectQuery != null)
        {
            objectQuery.EnablePlanCaching = false;
        }
        return query;
    }

    private static ObjectQuery GetObjectQuery<T>(IQueryable<T> query)
    {
        var objectQuery = query as ObjectQuery<T>;
        if (objectQuery == null)
        {
            var dbQuery = query as DbQuery<T>;
            if (dbQuery != null)
            {
                objectQuery = DbQueryToObjectQuery(dbQuery);
            }
        }
        return objectQuery;
    }

    public static ObjectQuery<T> DbQueryToObjectQuery<T>(DbQuery<T> dbQuery)
    {
        FieldInfo internalQueryField = dbQuery.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance)
            .FirstOrDefault(f => f.Name.Equals("_internalQuery"));
        var internalQuery = internalQueryField?.GetValue(dbQuery);
        FieldInfo objectQueryField = internalQuery?.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance)
            .FirstOrDefault(f => f.Name.Equals("_objectQuery"));
        var objectQuery = objectQueryField?.GetValue(internalQuery) as ObjectQuery<T>;
        return objectQuery;
    }