Entity Framework's 6's `ObjectQuery.Enable

2019-09-06 14:55发布

问题:

This article explains that query plan caching can be deactivated by setting EnablePlanCaching to false on the ObjectQuery, and also that it is enabled by default in EF6.

Alas, EF6 doesn't have an ObjectQuery, the DbSet's give you DbQuerys.

I don't think I can get an ObjectQuery from the DbQuery, and I certainly don't want to use the old ObjectContext. So is that it or is there a way to disable plan caching in EF6?

回答1:

Here is an extension method that will let you get an ObjectQuery from the DbSet

using (var ctx = new TestContext())
{
    var query = ctx.Products;
    query.GetObjectQuery().EnablePlanCaching = false;
    var list = query.ToList();
}


namespace Z.EntityFramework.Plus
{
    internal static partial class InternalExtensions
    {
        /// <summary>An IQueryable&lt;TEntity&gt; extension method that get the ObjectQuery from the query.</summary>
        /// <typeparam name="T">The type of elements of the query.</typeparam>
        /// <param name="query">The query to get the ObjectQuery from.</param>
        /// <returns>The ObjectQuery from the query.</returns>
        internal static ObjectQuery<T> GetObjectQuery<T>(this IQueryable<T> query)
        {
            // CHECK for ObjectQuery
            var objectQuery = query as ObjectQuery<T>;
            if (objectQuery != null)
            {
                return objectQuery;
            }

            // CHECK for DbQuery
            var dbQuery = query as DbQuery<T>;

            if (dbQuery == null)
            {
                throw new Exception("Oops! A general error has occurred. Please report the issue including the stack trace to our support team: info@zzzprojects.com");
            }

            var internalQueryProperty = dbQuery.GetType().GetProperty("InternalQuery", BindingFlags.NonPublic | BindingFlags.Instance);
            var internalQuery = internalQueryProperty.GetValue(dbQuery, null);
            var objectQueryContextProperty = internalQuery.GetType().GetProperty("ObjectQuery", BindingFlags.Public | BindingFlags.Instance);
            var objectQueryContext = objectQueryContextProperty.GetValue(internalQuery, null);

            objectQuery = objectQueryContext as ObjectQuery<T>;

            return objectQuery;
        }
    }
}