/// <summary>
        /// Find the ObjectContext from the given expression and cache it for future queries.
        /// </summary>
        protected Expression DiscoverContext(Expression expression)
        {
            Type type = expression is MemberExpression ? ((MemberExpression)expression).Type :
                        expression is MethodCallExpression && ((MethodCallExpression)expression).Object != null ?
                        ((MethodCallExpression)expression).Object.Type : expression.Type;

            if (type.IsGenericType && (type.GetGenericTypeDefinition() == typeof(ObjectQuery <>) ||
                                       type.GetGenericTypeDefinition() == typeof(ObjectSet <>)))
            {
                // Example: "System.Data.Objects.ObjectSet`1[[B1.Utility.DatabaseSetup.ModelsSecond.AppConfigParameter, B1.Utility.DatabaseSetup, Version=1.13.1.0, Culture=neutral, PublicKeyToken=null]]"
                string objectSetTypeName = type.FullName;

                // Example: "B1.Utility.DatabaseSetup.ModelsSecond.AppConfigParameter"
                string entityTypeName   = ObjectContext.GetObjectType(type.GetGenericArguments()[0]).FullName;
                string contextClassName = type.FullName; //?? ((MemberExpression) expression).Member.DeclaringType.FullName;

                // Get the expression which can be evaluated to get the ObjectContext
                Expression expressionToRun = expression is MemberExpression ? (MemberExpression)expression :
                                             expression is MethodCallExpression ? ((MethodCallExpression)expression).Object : null;

                // Ensure that the Context is stored
                ObjectContext entityContext = EntityContextCache.Contexts.GetOrAdd(contextClassName,
                                                                                   () => { return(((ObjectQuery)Expression.Lambda(expressionToRun).Compile().DynamicInvoke()).Context ?? _defaultContext); });

                // Ensure that the Storage meta data is loaded into cache
                EntityContextCache.EnsureStorageMetaData(entityContext);

                // Map the type names for the collection of entities and the entity to the context so that
                // subsequent encounter of these types results in context look up
                EntityContextCache.TypesToContexts.GetOrAdd(objectSetTypeName, () => { return(entityContext); });
                EntityContextCache.TypesToContexts.GetOrAdd(entityTypeName, () => { return(entityContext); });
            }

            return(expression);
        }
        /// <summary>
        /// Constructor for ContextVisitor takes the query expression.
        /// </summary>
        /// <param name="queryable">Query expression</param>
        public ContextVisitor(IQueryable queryable)
        {
            if (queryable.GetType().IsGenericType&& (queryable.GetType().GetGenericTypeDefinition() == typeof(ObjectQuery <>) ||
                                                     queryable.GetType().GetGenericTypeDefinition() == typeof(ObjectSet <>)))
            {
                _defaultContext = ((ObjectQuery)queryable).Context;
                EntityContextCache.EnsureStorageMetaData(_defaultContext);
            }

            // Visit the expression to discover if any other ObjectContext is used (cross-model query)
            Visit(queryable.Expression);
        }
 /// <summary>
 /// Get the QualifiedEntity which has the entity name and the schema name.
 /// </summary>
 /// <param name="dotNetEntityType">Entity type</param>
 /// <returns>QualifiedEntity for the given entity type.</returns>
 public QualifiedEntity GetQualifiedEntity(Type dotNetEntityType)
 {
     return(EntityContextCache.StorageMetaData.Get(
                EntityContextCache.GetMappingTypeName(dotNetEntityType, _defaultContext)));
 }
 /// <summary>
 /// Check if the entity already exists in the cache.
 /// </summary>
 /// <param name="dotNetEntityType">Entity type</param>
 /// <returns>True if exists in the cache else false</returns>
 public bool EntityExists(Type dotNetEntityType)
 {
     return(EntityContextCache.ExistsMappingTypeName(dotNetEntityType, _defaultContext));
 }