コード例 #1
0
        public static IQueryable <TEntity> AsNoFilter <TEntity>(this DbSet <TEntity> query) where TEntity : class
#endif
        {
            var queryFilterQueryable = QueryFilterManager.GetFilterQueryable(query);

            return(queryFilterQueryable != null ? (IQueryable <TEntity>)queryFilterQueryable.GetOriginalQuery() : query);
        }
コード例 #2
0
        /// <summary>Gets database expression.</summary>
        /// <param name="context">The context.</param>
        /// <param name="type">The type.</param>
        /// <returns>The database expression.</returns>
        public override DbExpression GetDbExpression(DbContext context, Type type)
        {
            var contextFullName = context.GetType().AssemblyQualifiedName ?? context.GetType().FullName;
            var typeFullName    = type.AssemblyQualifiedName ?? type.FullName;
            var hookId          = QueryFilterManager.PrefixHook + contextFullName + ";" + typeFullName + ";" + UniqueKey;

            if (!QueryFilterManager.DbExpressionByHook.ContainsKey(hookId))
            {
                // CREATE set
                var setMethod = typeof(DbContext).GetMethod("Set", new Type[0]).MakeGenericMethod(type);
                var dbSet     = (IQueryable <T>)setMethod.Invoke(context, null);

                // APPLY filter
                dbSet = Filter(dbSet);

                // APPLY hook
                dbSet = QueryFilterManager.HookFilter(dbSet, hookId);

                // HOOK the filter
                var objectQuery = dbSet.GetObjectQuery();
                var commandTextAndParameters = objectQuery.GetCommandTextAndParameters();

                // ADD parameter
                QueryFilterManager.DbExpressionParameterByHook.AddOrUpdate(QueryFilterManager.DbExpressionByHook[hookId], commandTextAndParameters.Item2, (s, list) => list);
            }

            // TODO: WeakTable ?
            return(QueryFilterManager.DbExpressionByHook[hookId]);
        }
コード例 #3
0
        /// <summary>Constructor.</summary>
        /// <param name="dbSetProperty">The database set property.</param>
        public QueryFilterSet(DbContext context, PropertyInfo dbSetProperty)
        {
            // NOT longer used?
            // CreateFilterQueryableCompiled = new Lazy<Func<DbContext, QueryFilterSet, object, IQueryable>>(CompileCreateFilterQueryable);
            DbSetProperty    = dbSetProperty;
            ElementType      = dbSetProperty.PropertyType.GetDbSetElementType();
            GetDbSetCompiled = new Lazy <Func <DbContext, IQueryable> >(() => CompileGetDbSet(dbSetProperty));

            // UpdateInternalQueryCompiled
            {
                Action <DbContext, ObjectQuery> compiled;
                if (!CachedActions.TryGetValue(dbSetProperty, out compiled))
                {
                    compiled = CompileUpdateInternalQuery(dbSetProperty);
                    CachedActions.TryAdd(dbSetProperty, compiled);
                }
                UpdateInternalQueryCompiled = compiled;
            }

            {
                var currentQuery = dbSetProperty.GetValue(context, null);
                currentQuery  = QueryFilterManager.HookFilter2((IQueryable)currentQuery, ElementType, QueryFilterManager.PrefixFilterID);
                OriginalQuery = (IQueryable)currentQuery;
            }
        }
コード例 #4
0
        /// <summary>Disable this filter on the specified types.</summary>
        /// <param name="types">A variable-length parameters list containing types to disable the filter on.</param>
        public void Disable(params Type[] types)
        {
            if (types == null || types.Length == 0)
            {
                if (IsFilterEnabledList.Count == 0)
                {
                    IsDefaultEnabled = false;
                }
                else
                {
                    IsFilterEnabledList.Add(type1 => false);
                }
            }
            else
            {
                foreach (var type in types)
                {
                    IsFilterEnabledList.Add(type1 => type.IsAssignableFrom(type1) ? false : (bool?)null);
                }
            }

            if (OwnerContext != null)
            {
                OwnerContext.ClearCache();
            }
            else
            {
                QueryFilterManager.ClearAllCache();
            }
        }
コード例 #5
0
        /// <summary>Gets database expression.</summary>
        /// <param name="context">The context.</param>
        /// <param name="type">The type.</param>
        /// <returns>The database expression.</returns>
        public override DbExpression GetDbExpression(DbContext context, Type type)
        {
            var contextFullName = context.GetType().AssemblyQualifiedName ?? context.GetType().FullName;
            var typeFullName    = type.AssemblyQualifiedName ?? type.FullName;
            var hookId          = QueryFilterManager.PrefixHook + contextFullName + ";" + typeFullName + ";" + UniqueKey;

            if (!QueryFilterManager.DbExpressionByHook.ContainsKey(hookId))
            {
                // CREATE set
                var setMethod = typeof(DbContext).GetMethod("Set", new Type[0]).MakeGenericMethod(type);
                var dbSet     = (IQueryable <T>)setMethod.Invoke(context, null);

                // APPLY filter
                dbSet = Filter(dbSet);

                // APPLY hook
                dbSet = QueryFilterManager.HookFilter(dbSet, hookId);

                // Hook the filter
                var objectQuery = dbSet.GetObjectQuery();
                objectQuery.ToTraceString();
            }

            // TODO: WeakTable ?
            return(QueryFilterManager.DbExpressionByHook[hookId]);
        }
コード例 #6
0
        public static IQueryable <T> AsNoFilter <T>(this DbSet <T> query) where T : class
#endif
        {
            var queryFilterQueryable = QueryFilterManager.GetFilterQueryable(query);

            return(queryFilterQueryable != null ? (IQueryable <T>)queryFilterQueryable.OriginalQuery : query);
        }
コード例 #7
0
 /// <summary>Clears the cache.</summary>
 public void ClearCache()
 {
     if (ClearCacheRequired)
     {
         QueryFilterManager.ClearQueryCache(Context);
         ClearCacheRequired = false;
     }
 }
コード例 #8
0
        public static IQueryable <TEntity> Filter <TEntity>(this DbSet <TEntity> query, params object[] keys) where TEntity : class
#endif
        {
            var queryFilterQueryable = QueryFilterManager.GetFilterQueryable(query);
            var context       = queryFilterQueryable != null ? queryFilterQueryable.Context : query.GetDbContext();
            var filterContext = QueryFilterManager.AddOrGetFilterContext(context);

            return(filterContext.ApplyFilter(query, keys));
        }
コード例 #9
0
        public static IQueryable <T> Filter <T>(this DbSet <T> query, params object[] keys) where T : class
#endif
        {
            var queryFilterQueryable = QueryFilterManager.GetFilterQueryable(query);
            var nonQueryFilter       = queryFilterQueryable != null ? (IQueryable <T>)queryFilterQueryable.OriginalQuery : query;

            var context       = queryFilterQueryable != null ? queryFilterQueryable.Context : query.GetDbContext();
            var filterContext = QueryFilterManager.AddOrGetFilterContext(context);

            return(filterContext.ApplyFilter(nonQueryFilter, keys));
        }
コード例 #10
0
        /// <summary>
        ///     Creates and return a filter associated with the specified key added for the context.
        /// </summary>
        /// <typeparam name="T">The type of elements of the query.</typeparam>
        /// <param name="context">The context filtered.</param>
        /// <param name="key">The filter key associated to the filter.</param>
        /// <param name="queryFilter">The query filter to apply to the the context.</param>
        /// <param name="isEnabled">true if the filter is enabled.</param>
        /// <returns>The filter created and added to the the context.</returns>
        public static BaseQueryFilter Filter <T>(this DbContext context, object key, Func <IQueryable <T>, IQueryable <T> > queryFilter, bool isEnabled = true)
        {
            var filterContext = QueryFilterManager.AddOrGetFilterContext(context);
            var filter        = filterContext.AddFilter(key, queryFilter);

            if (isEnabled)
            {
                filter.Enable();
            }

            return(filter);
        }
コード例 #11
0
        public void UpdateHook(DbContext context)
        {
            var filterID = QueryFilterManager.PrefixFilterID + GetFilterUniqueID();

            // Hook on every set
            foreach (var set in FilterSets)
            {
                var currentQuery = set.OriginalQuery;

                var newQuery = QueryFilterManager.HookFilter2((IQueryable)currentQuery, set.ElementType, filterID);

                set.UpdateInternalQueryCompiled(Context, newQuery.GetObjectQuery());
            }
        }
コード例 #12
0
        /// <summary>Constructor.</summary>
        /// <param name="dbSetProperty">The database set property.</param>
        public QueryFilterSet(DbContext context, PropertyInfo dbSetProperty)
        {
            CreateFilterQueryableCompiled = new Lazy <Func <DbContext, QueryFilterSet, object, IQueryable> >(CompileCreateFilterQueryable);
            DbSetProperty               = dbSetProperty;
            ElementType                 = dbSetProperty.PropertyType.GetDbSetElementType();
            GetDbSetCompiled            = new Lazy <Func <DbContext, IQueryable> >(() => CompileGetDbSet(dbSetProperty));
            UpdateInternalQueryCompiled = new Lazy <Action <DbContext, ObjectQuery> >(() => CompileUpdateInternalQuery(dbSetProperty));

            {
                var currentQuery = dbSetProperty.GetValue(context, null);
                currentQuery  = QueryFilterManager.HookFilter2((IQueryable)currentQuery, ElementType, QueryFilterManager.PrefixFilterID);
                OriginalQuery = (IQueryable)currentQuery;
            }
        }
コード例 #13
0
        /// <summary>Create a new QueryFilterContext.</summary>
        /// <param name="context">The context associated to the filter context.</param>
        /// <param name="isGenericContext">true if this filter context is the generic context used by other filter context.</param>
        public QueryFilterContext(DbContext context, bool isGenericContext)
        {
            if (isGenericContext)
            {
                LoadGenericContextInfo(context);
            }
            else
            {
                Context = context;
                Filters = new Dictionary <object, BaseQueryFilter>();

                var genericContext = QueryFilterManager.AddOrGetGenericFilterContext(context);
                FilterSetByType = genericContext.FilterSetByType;
                FilterSets      = genericContext.FilterSets;
            }
        }
コード例 #14
0
        public static IQueryable <T> SetFiltered <T>(this DbContext context) where T : class
        {
            var filterContext = QueryFilterManager.AddOrGetFilterContext(context);

            if (filterContext.FilterSetByType.ContainsKey(typeof(T)))
            {
                var set = filterContext.FilterSetByType[typeof(T)];

                if (set.Count == 1)
                {
                    return((IQueryable <T>)set[0].DbSetProperty.GetValue(context, null));
                }
                throw new Exception(ExceptionMessage.QueryFilter_SetFilteredManyFound);
            }

            throw new Exception(ExceptionMessage.QueryFilter_SetFilteredNotFound);
        }
コード例 #15
0
        /// <summary>
        ///     Filter the query using context filters associated with specified keys.
        /// </summary>
        /// <typeparam name="T">The type of elements of the query.</typeparam>
        /// <param name="query">The query to filter using context filters associated with specified keys.</param>
        /// <param name="keys">
        ///     A variable-length parameters list containing keys associated to context filters to use to filter the
        ///     query.
        /// </param>
        /// <returns>The query filtered using context filters associated with specified keys.</returns>
        public static IQueryable <T> Filter <T>(this IDbSet <T> query, params object[] keys) where T : class
        {
            var filterContext = QueryFilterManager.AddOrGetFilterContext(query.GetDbContext());
            var filterHook    = QueryFilterManager.EnableFilterById;

            var sb = new StringBuilder();

            if (keys != null)
            {
                foreach (var key in keys)
                {
                    var filter = filterContext.GetFilter(key);
                    if (filter == null)
                    {
                        continue;
                    }
                    sb.Append(filter.UniqueKey);
                    sb.Append(";");
                }
            }

            return(QueryFilterManager.HookFilter(query.AsNoFilter(), filterHook + sb));
        }
コード例 #16
0
        /// <summary>Gets the filter associated with the specified key from the context.</summary>
        /// <param name="context">The context filtered.</param>
        /// <param name="key">The filter key associated to the filter.</param>
        /// <returns>The filter associated with the specified key from the context.</returns>
        public static BaseQueryFilter Filter(this DbContext context, object key)
        {
            var filterContext = QueryFilterManager.AddOrGetFilterContext(context);

            return(filterContext.GetFilter(key));
        }
        /// <summary>
        ///     This method is called after a new
        ///     <see cref="T:System.Data.Entity.Core.Common.CommandTrees.DbCommandTree" /> has been created.
        ///     The tree that is used after interception can be changed by setting
        ///     <see cref="P:System.Data.Entity.Infrastructure.Interception.DbCommandTreeInterceptionContext.Result" />
        ///     while intercepting.
        /// </summary>
        /// <param name="interceptionContext">Contextual information associated with the call.</param>
        public void TreeCreated(DbCommandTreeInterceptionContext interceptionContext)
        {
            var dbQueryCommandTree = interceptionContext.Result as DbQueryCommandTree;

            if (dbQueryCommandTree != null && interceptionContext.DbContexts.Count() == 1)
            {
                var context = interceptionContext.DbContexts.First();

                // Visit first to find filter ID && hook
                var visitorFilter = new QueryFilterInterceptorDbFilterExpression();
                var queryFiltered = dbQueryCommandTree.Query.Accept(visitorFilter);

                if (!string.IsNullOrEmpty(visitorFilter.HookID))
                {
                    if (!QueryFilterManager.DbExpressionByHook.ContainsKey(visitorFilter.HookID))
                    {
                        QueryFilterManager.DbExpressionByHook.TryAdd(visitorFilter.HookID, queryFiltered);
                    }
                }
                else
                {
                    var filterByContext = QueryFilterManager.AddOrGetFilterContext(context);
                    filterByContext.ClearCacheRequired = true;

                    var filterQuery = new QueryFilterInterceptorApply
                    {
                        InstanceFilters = filterByContext
                    };

                    if (visitorFilter.FilterID != null && visitorFilter.FilterID.Count > 0)
                    {
                        foreach (var filter in visitorFilter.FilterID)
                        {
                            if (filter == QueryFilterManager.DisableAllFilter)
                            {
                                // Disable all filter in the context!
                                filterQuery.ApplyFilterList.Add(interceptorFilter => false);
                            }
                            else if (filter.StartsWith(QueryFilterManager.EnableFilterById, StringComparison.InvariantCulture))
                            {
                                // Enable all specific filter
                                var filters = filter.Substring(QueryFilterManager.EnableFilterById.Length).Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries);

                                if (filters.Length == 0)
                                {
                                    filterQuery.ApplyFilterList.Add(interceptorFilter => false);
                                }
                                foreach (var applyFilter in filters)
                                {
                                    filterQuery.ApplyFilterList.Add(interceptorFilter => interceptorFilter.UniqueKey.ToString() == applyFilter ? true : (bool?)null);
                                }
                            }
                        }
                    }

                    // VISIT filter
                    var visitor = new QueryFilterInterceptorDbScanExpression
                    {
                        Context = context,
                        InstanceFilterContext = filterByContext,
                        FilterQuery           = filterQuery
                    };

                    var newQuery = queryFiltered.Accept(visitor);

                    // CREATE a new Query
                    interceptionContext.Result = new DbQueryCommandTree(dbQueryCommandTree.MetadataWorkspace, dbQueryCommandTree.DataSpace, newQuery, true);
                }
            }
        }
コード例 #18
0
 /// <summary>Return the orginal query before the context was filtered.</summary>
 /// <typeparam name="T">The type of elements of the query.</typeparam>
 /// <param name="query">The filtered query from which the original query should be retrieved.</param>
 /// <returns>The orginal query before the context was filtered.</returns>
 public static IQueryable <T> AsNoFilter <T>(this IDbSet <T> query) where T : class
 {
     return(QueryFilterManager.HookFilter(query, QueryFilterManager.DisableAllFilter));
 }