예제 #1
0
        public static IEnumerable <SelectColumn> GetSelectableColumns(AutoQueryableProfile profile, Type entityType, SelectInclusingType selectInclusingType = SelectInclusingType.IncludeBaseProperties)
        {
            IEnumerable <SelectColumn> columns = null;
            bool isCollection = entityType.IsEnumerable();
            var  type         = entityType;

            if (isCollection)
            {
                type = entityType.GetGenericArguments().FirstOrDefault();
            }
            // Get all properties without navigation properties.
            if (selectInclusingType == SelectInclusingType.IncludeBaseProperties)
            {
                columns = type.GetProperties(BindingFlags.Public | BindingFlags.Instance)
                          .Where(p =>
                                 (p.PropertyType.GetTypeInfo().IsGenericType&& p.PropertyType.GetTypeInfo().GetGenericTypeDefinition() == typeof(Nullable <>)) ||
                                 (!p.PropertyType.GetTypeInfo().IsClass&& !p.PropertyType.GetTypeInfo().IsGenericType) ||
                                 p.PropertyType.GetTypeInfo().IsArray ||
                                 p.PropertyType == typeof(string)
                                 )
                          .Select(p => new SelectColumn
                {
                    Key  = p.Name,
                    Name = p.Name,
                    Type = p.PropertyType
                });
            }
            // Get all properties.
            else if (selectInclusingType == SelectInclusingType.IncludeAllProperties)
            {
                columns = type.GetProperties(BindingFlags.Public | BindingFlags.Instance)
                          .Select(p => new SelectColumn
                {
                    Key  = p.Name,
                    Name = p.Name,
                    Type = p.PropertyType
                });
            }

            // Remove non selectable properties.
            if (profile?.SelectableProperties != null)
            {
                columns = columns?.Where(c => profile.SelectableProperties.Contains(c.Name, StringComparer.OrdinalIgnoreCase));
            }

            // Remove unselectable properties.
            if (profile?.UnselectableProperties != null)
            {
                columns = columns?.Where(c => !profile.UnselectableProperties.Contains(c.Name, StringComparer.OrdinalIgnoreCase));
            }

            return(columns?.ToList());
        }
        public Clauses GetClauses(string[] queryStringParts, AutoQueryableProfile profile)
        {
            var clauses = new Clauses();

            foreach (string q in queryStringParts)
            {
                if (q.Contains(ClauseAlias.Select, StringComparison.OrdinalIgnoreCase) && profile.IsClauseAllowed(ClauseType.Select))
                {
                    clauses.Select = GetClause(q, ClauseAlias.Select, ClauseType.Select);
                }
                else if (q.Contains(ClauseAlias.Top, StringComparison.OrdinalIgnoreCase) && profile.IsClauseAllowed(ClauseType.Top))
                {
                    clauses.Top = GetClause(q, ClauseAlias.Top, ClauseType.Top);
                }
                else if (q.Contains(ClauseAlias.Take, StringComparison.OrdinalIgnoreCase) && profile.IsClauseAllowed(ClauseType.Top))
                {
                    clauses.Top = GetClause(q, ClauseAlias.Take, ClauseType.Top);
                }
                else if (q.Contains(ClauseAlias.Skip, StringComparison.OrdinalIgnoreCase) && profile.IsClauseAllowed(ClauseType.Skip))
                {
                    clauses.Skip = GetClause(q, ClauseAlias.Skip, ClauseType.Skip);
                }
                else if (q.Contains(ClauseAlias.First, StringComparison.OrdinalIgnoreCase) && profile.IsClauseAllowed(ClauseType.First))
                {
                    clauses.First = new Clause {
                        ClauseType = ClauseType.First
                    };
                }
                else if (q.Contains(ClauseAlias.Last, StringComparison.OrdinalIgnoreCase) && profile.IsClauseAllowed(ClauseType.Last))
                {
                    clauses.Last = new Clause {
                        ClauseType = ClauseType.Last
                    };
                }
                else if (q.Contains(ClauseAlias.OrderBy, StringComparison.OrdinalIgnoreCase) && profile.IsClauseAllowed(ClauseType.OrderBy))
                {
                    clauses.OrderBy = GetClause(q, ClauseAlias.OrderBy, ClauseType.OrderBy);
                }
                else if (q.Contains(ClauseAlias.OrderByDesc, StringComparison.OrdinalIgnoreCase) && profile.IsClauseAllowed(ClauseType.OrderByDesc))
                {
                    clauses.OrderByDesc = GetClause(q, ClauseAlias.OrderByDesc, ClauseType.OrderByDesc);
                }
                else if (q.Contains(ClauseAlias.WrapWith, StringComparison.OrdinalIgnoreCase) && profile.IsClauseAllowed(ClauseType.WrapWith))
                {
                    clauses.WrapWith = GetClause(q, ClauseAlias.WrapWith, ClauseType.WrapWith);
                }
            }
            return(clauses);
        }
예제 #3
0
        public FilterTest()
        {
            var settings = new AutoQueryableSettings();
            IAutoQueryableProfile profile = new AutoQueryableProfile(settings);

            _queryStringAccessor = new SimpleQueryStringAccessor();
            var selectClauseHandler     = new DefaultSelectClauseHandler();
            var orderByClauseHandler    = new DefaultOrderByClauseHandler();
            var wrapWithClauseHandler   = new DefaultWrapWithClauseHandler();
            var clauseMapManager        = new ClauseMapManager(selectClauseHandler, orderByClauseHandler, wrapWithClauseHandler, profile);
            var clauseValueManager      = new ClauseValueManager(selectClauseHandler, orderByClauseHandler, wrapWithClauseHandler, profile);
            var criteriaFilterManager   = new CriteriaFilterManager();
            var defaultAutoQueryHandler = new AutoQueryHandler(_queryStringAccessor, criteriaFilterManager, clauseMapManager, clauseValueManager, profile);

            _autoQueryableContext = new AutoQueryableContext(defaultAutoQueryHandler);
        }
        /// <summary>
        /// Adds the minimum essential AutoQueryable services to the specified <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection" />. Additional services
        /// including default clause handlers.
        /// </summary>
        /// <param name="services">The <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection" /> to add services to.</param>
        /// <param name="handler">An <see cref="T:System.Action`1" /> to configure the provided <see cref="T:AutoQueryable.Core.Models.AutoQueryableProfile" />.</param>
        /// <returns>An <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection" /> that can be used to further other services.</returns>
        public static IServiceCollection AddAutoQueryable(this IServiceCollection services, Action <AutoQueryableProfile> handler = null)
        {
            var profile = new AutoQueryableProfile();

            handler?.Invoke(profile);
            services.AddScoped <IAutoQueryableContext, AutoQueryableContext>();
            services.AddScoped <IAutoQueryableProfile, AutoQueryableProfile>(_ => profile);
            services.AddScoped <IAutoQueryHandler, AutoQueryHandler>();
            services.AddScoped <IClauseValueManager, ClauseValueManager>();
            services.AddScoped <ICriteriaFilterManager, CriteriaFilterManager>();
            services.AddScoped <IClauseMapManager, ClauseMapManager>();
            services.AddScoped <ISelectClauseHandler, DefaultSelectClauseHandler>();
            services.AddScoped <IOrderByClauseHandler, DefaultOrderByClauseHandler>();
            services.AddScoped <IWrapWithClauseHandler, DefaultWrapWithClauseHandler>();
            return(services);
        }
예제 #5
0
        public static bool IsClauseAllowed(this AutoQueryableProfile profile, ClauseType clauseType)
        {
            bool isClauseAllowed = true;
            bool?isAllowed       = profile?.AllowedClauses?.HasFlag(clauseType);
            bool?isDisallowed    = profile?.DisAllowedClauses?.HasFlag(clauseType);

            if (isAllowed.HasValue && !isAllowed.Value)
            {
                isClauseAllowed = false;
            }

            if (isDisallowed.HasValue && isDisallowed.Value)
            {
                isClauseAllowed = false;
            }
            return(isClauseAllowed);
        }
예제 #6
0
        public static bool IsWrapperPartAllowed(this AutoQueryableProfile profile, WrapperPartType wrapperPartType)
        {
            bool isWrapperPartAllowed = true;
            bool?isAllowed            = profile?.AllowedWrapperPartType?.HasFlag(wrapperPartType);
            bool?isDisallowed         = profile?.DisAllowedWrapperPartType?.HasFlag(wrapperPartType);

            if (isAllowed.HasValue && !isAllowed.Value)
            {
                isWrapperPartAllowed = false;
            }

            if (isDisallowed.HasValue && isDisallowed.Value)
            {
                isWrapperPartAllowed = false;
            }
            return(isWrapperPartAllowed);
        }
예제 #7
0
 private void ProcessInclusingType(AutoQueryableProfile profile, ICollection <SelectColumn> selectColumns)
 {
     foreach (var selectColumn in selectColumns)
     {
         if (selectColumn.InclusionType != SelectInclusingType.Default)
         {
             var selectableColumns = GetSelectableColumns(profile, selectColumn.Type, selectColumn.InclusionType);
             foreach (var columnName in selectableColumns)
             {
                 if (!selectColumn.SubColumns.Any(x => x.Name.Equals(columnName, StringComparison.OrdinalIgnoreCase)))
                 {
                     var subColumnKey = selectColumn.Key + "." + columnName;
                     // pass non selectable properties.
                     if (profile?.SelectableProperties != null &&
                         !profile.SelectableProperties.Contains(subColumnKey, StringComparer.OrdinalIgnoreCase))
                     {
                         continue;
                     }
                     // pass unselectable properties.
                     if (profile?.UnselectableProperties != null &&
                         profile.UnselectableProperties.Contains(subColumnKey, StringComparer.OrdinalIgnoreCase))
                     {
                         continue;
                     }
                     var type = selectColumn.Type;
                     if (selectColumn.Type.IsEnumerable())
                     {
                         type = selectColumn.Type.GetGenericArguments().FirstOrDefault();
                     }
                     var column = new SelectColumn
                     {
                         Key          = subColumnKey,
                         Name         = columnName,
                         SubColumns   = new List <SelectColumn>(),
                         Type         = type.GetProperties().Single(x => x.Name == columnName).PropertyType,
                         ParentColumn = selectColumn
                     };
                     selectColumn.SubColumns.Add(column);
                 }
             }
         }
         ProcessInclusingType(profile, selectColumn.SubColumns);
     }
 }
예제 #8
0
        public Clauses GetClauses(string[] queryStringParts, AutoQueryableProfile profile)
        {
            var clauses = new Clauses();

            foreach (string q in queryStringParts)
            {
                if (q.Contains(ClauseAlias.Select, StringComparison.OrdinalIgnoreCase) && profile.IsClauseAllowed(ClauseType.Select))
                {
                    clauses.Select = GetClause(q, ClauseAlias.Select, ClauseType.Select);
                }
                else if (q.Contains(ClauseAlias.Top, StringComparison.OrdinalIgnoreCase) && profile.IsClauseAllowed(ClauseType.Top))
                {
                    clauses.Top = GetClause(q, ClauseAlias.Top, ClauseType.Top);
                }
                else if (q.Contains(ClauseAlias.Skip, StringComparison.OrdinalIgnoreCase) && profile.IsClauseAllowed(ClauseType.Skip))
                {
                    clauses.Skip = GetClause(q, ClauseAlias.Skip, ClauseType.Skip);
                }
                else if (q.Contains(ClauseAlias.OrderBy, StringComparison.OrdinalIgnoreCase) && profile.IsClauseAllowed(ClauseType.OrderBy))
                {
                    clauses.OrderBy = GetClause(q, ClauseAlias.OrderBy, ClauseType.OrderBy);
                }
                else if (q.Contains(ClauseAlias.Filter, StringComparison.OrdinalIgnoreCase) && profile.IsClauseAllowed(ClauseType.Filter))
                {
                    clauses.Filter = GetClause(q, ClauseAlias.Filter, ClauseType.Filter);
                }
                else if (q.Contains(ClauseAlias.Expand, StringComparison.OrdinalIgnoreCase) && profile.IsClauseAllowed(ClauseType.Expand))
                {
                    clauses.Expand = GetClause(q, ClauseAlias.Expand, ClauseType.Expand);
                }
                else if (q.Contains(ClauseAlias.Search, StringComparison.OrdinalIgnoreCase) && profile.IsClauseAllowed(ClauseType.Search))
                {
                    clauses.Search = GetClause(q, ClauseAlias.Search, ClauseType.Search);
                }
            }
            return(clauses);
        }
예제 #9
0
        public static IEnumerable <Column> GetOrderByColumns(AutoQueryableProfile profile, Clause orderClause, Type entityType)
        {
            if (orderClause == null)
            {
                return(null);
            }
            IEnumerable <PropertyInfo> properties = entityType.GetProperties();

            if (profile?.SortableProperties != null)
            {
                properties = properties.Where(c => profile.SortableProperties.Contains(c.Name, StringComparer.OrdinalIgnoreCase));
            }
            if (profile?.UnSortableProperties != null)
            {
                properties = properties.Where(c => !profile.UnSortableProperties.Contains(c.Name, StringComparer.OrdinalIgnoreCase));
            }
            string[] columns = orderClause.Value.Split(',');
            properties = properties.Where(p => columns.Contains(p.Name, StringComparer.OrdinalIgnoreCase));

            return(properties.Select(v => new Column
            {
                PropertyName = v.Name
            }));
        }
예제 #10
0
        public static dynamic GetAutoQuery <TEntity>(string queryString, Type entityType, IQueryable <TEntity> query, AutoQueryableProfile profile) where TEntity : class
        {
            if (string.IsNullOrEmpty(queryString))
            {
                IEnumerable <string> columns = SelectHelper.GetSelectableColumns(profile?.UnselectableProperties, entityType);
                return(query.Select(SelectHelper.GetSelector <TEntity>(string.Join(",", columns.ToArray()))));
            }
            string[] queryStringParts = queryString.Replace("?", "").Split('&');

            IList <Criteria> criterias = CriteriaManager.GetCriterias(entityType, queryStringParts).ToList();
            IList <Clause>   clauses   = ClauseManager.GetClauses(queryStringParts).ToList();

            Clause wrapWithClause = clauses.FirstOrDefault(c => c.ClauseType == ClauseType.WrapWith);
            var    countAllRows   = false;
            IEnumerable <WrapperPartType> wrapperParts = null;

            if (wrapWithClause != null)
            {
                wrapperParts = WrapperManager.GetWrapperParts(wrapWithClause.Value.Split(',')).ToList();
                countAllRows = wrapperParts.Contains(WrapperPartType.TotalCount);
            }

            QueryResult queryResult = QueryBuilder.Build(query, entityType, clauses, criterias, profile?.UnselectableProperties, countAllRows);

            if (wrapWithClause == null)
            {
                return(queryResult.Result);
            }

            return(WrapperManager.GetWrappedResult(wrapperParts, queryResult, clauses, queryString));
        }
예제 #11
0
        public static MemberInitExpression InitType <TEntity>(IEnumerable <SelectColumn> columns, Expression node, AutoQueryableProfile profile)
        {
            var expressions = new Dictionary <string, Expression>();

            foreach (SelectColumn subColumn in columns)
            {
                Expression ex = GetMemberExpression <TEntity>(node, subColumn, profile);
                expressions.Add(subColumn.Name, ex);
            }

            Type type = null;

            if (profile.UseBaseType)
            {
                type = node.Type;
            }
            else
            {
                var properties = GetTypeProperties(expressions);
                type = RuntimeTypeBuilder.GetRuntimeType(node.Type, properties);
            }
            NewExpression ctor = Expression.New(type);

            return(Expression.MemberInit(ctor, expressions.Select(p => Expression.Bind(type.GetProperty(p.Key, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance), p.Value))));
        }
예제 #12
0
        private static Expression GetMemberExpression <TEntity>(Expression parent, SelectColumn column, AutoQueryableProfile profile, bool isLambdaBody = false)
        {
            bool isCollection = parent.Type.IsEnumerableButNotString();

            // If the current column has no sub column, return the final property.
            if (!column.HasSubColumn && !isCollection)
            {
                if (!parent.Type.PropertyExist(column.Name))
                {
                    return(null);
                }
                return(Expression.PropertyOrField(parent, column.Name));
            }

            Expression nextParent = parent;

            // If we are not inside a select lambda, the next parent will be the current column
            if (!isLambdaBody)
            {
                if (!parent.Type.PropertyExist(column.Name))
                {
                    return(null);
                }
                var ex = Expression.PropertyOrField(parent, column.Name);
                // Current column is a collection, let's create a select lambda, eg: SalesOrderDetail.Select(x => x.LineTotal)
                if (ex.Type.IsEnumerableButNotString())
                {
                    ParameterExpression param      = ex.CreateParameterFromGenericType();
                    Expression          lambdaBody = GetMemberExpression <TEntity>(param, column, profile, true);
                    return(ex.CreateSelect(lambdaBody, param));
                }
                else
                {
                    nextParent = Expression.PropertyOrField(parent, column.Name);
                }
            }

            return(InitType <TEntity>(column.SubColumns, nextParent, profile));
        }
예제 #13
0
        public static Expression <Func <TEntity, TResult> > GetSelector <TEntity, TResult>(IEnumerable <SelectColumn> columns, AutoQueryableProfile profile)
        {
            Dictionary <string, Expression> memberExpressions = new Dictionary <string, Expression>();

            ParameterExpression parameter = Expression.Parameter(typeof(TEntity), "p");

            MemberInitExpression memberInit = InitType <TEntity>(columns, parameter, profile);

            return(Expression.Lambda <Func <TEntity, TResult> >(memberInit, parameter));
        }
예제 #14
0
        public static dynamic GetAutoQuery <TEntity>(string queryString, Type entityType, IQueryable <TEntity> query, AutoQueryableProfile profile) where TEntity : class
        {
            // If query string empty select default entity properties.
            if (string.IsNullOrEmpty(queryString))
            {
                IColumnProvider            columnProvider = ProviderFactory.GetColumnProvider();
                IEnumerable <SelectColumn> selectColumns  = EntityColumnHelper.GetSelectableColumns(profile, entityType);
                if (profile.UseBaseType)
                {
                    return(query.Select(SelectHelper.GetSelector <TEntity, TEntity>(selectColumns, profile)));
                }
                return(query.Select(SelectHelper.GetSelector <TEntity, object>(selectColumns, profile)));
            }

            // Get criteria & clauses from choosen provider (AQ, OData, ...)
            string[]          queryStringParts = queryString.GetParts();
            ICriteriaProvider criteriaProvider = ProviderFactory.GetCriteriaProvider(profile?.ProviderType);
            IList <Criteria>  criterias        = profile.IsClauseAllowed(ClauseType.Filter) ? criteriaProvider.GetCriterias(entityType, queryStringParts, profile).ToList() : null;
            IClauseProvider   clauseProvider   = ProviderFactory.GetClauseProvider(profile?.ProviderType);
            Clauses           clauses          = clauseProvider.GetClauses(queryStringParts, profile);

            var countAllRows = false;
            IEnumerable <WrapperPartType> wrapperParts = null;

            if (clauses.WrapWith != null)
            {
                IWrapperProvider wrapperProvider = ProviderFactory.GetWrapperProvider();
                wrapperParts = wrapperProvider.GetWrapperParts(clauses.WrapWith.Value.Split(','), profile).ToList();
                countAllRows = wrapperParts.Contains(WrapperPartType.TotalCount);
            }

            QueryResult queryResult = QueryBuilder.Build(query, entityType, clauses, criterias, profile, countAllRows);

            if (clauses.WrapWith == null || !wrapperParts.Any())
            {
                return(queryResult.Result);
            }

            return(DefaultWrapperProvider.GetWrappedResult(wrapperParts, queryResult, clauses, queryString));
        }
        public static void AutoQueryable(this AfterPipeline afterPipeline, NancyContext context, dynamic query, AutoQueryableProfile profile = null)
        {
            context.Items.Add("autoqueryable-query", query);

            afterPipeline += ctx =>
            {
                if (query == null)
                {
                    throw new Exception("Unable to retreive value of IQueryable from context result.");
                }
                Type entityType = query.GetType().GenericTypeArguments[0];

                string queryString = ctx.Request.Url.Query;

                ctx.Response.Contents = stream =>
                {
                    using (var writer = new StreamWriter(stream))
                    {
                        var result = QueryableHelper.GetAutoQuery(queryString, entityType, query, profile);
                        writer.Write(JsonConvert.SerializeObject(result));
                    }
                };
            };
        }
예제 #16
0
        public static dynamic AutoQueryable <TEntity>(this IQueryable <TEntity> query, string queryString, AutoQueryableProfile profile = null) where TEntity : class
        {
            profile = profile ?? new AutoQueryableProfile();
            Type entityType = typeof(TEntity);

            return(QueryableHelper.GetAutoQuery(queryString, entityType, query, profile));
        }
예제 #17
0
 public IEnumerable <Criteria> GetCriterias(Type entityType, string[] queryStringParts, AutoQueryableProfile profile)
 {
     foreach (string qPart in queryStringParts)
     {
         string   q        = WebUtility.UrlDecode(qPart);
         Criteria criteria = null;
         if (q.Contains(ConditionAlias.NotEqual, StringComparison.OrdinalIgnoreCase) && profile.IsConditionAllowed(ConditionType.NotEqual))
         {
             criteria = GetCriteria(q, ConditionAlias.NotEqual, ConditionType.NotEqual, entityType);
         }
         else if (q.Contains(ConditionAlias.LessEqual, StringComparison.OrdinalIgnoreCase) && profile.IsConditionAllowed(ConditionType.LessEqual))
         {
             criteria = GetCriteria(q, ConditionAlias.LessEqual, ConditionType.LessEqual, entityType);
         }
         else if (q.Contains(ConditionAlias.Less, StringComparison.OrdinalIgnoreCase) && profile.IsConditionAllowed(ConditionType.Less))
         {
             criteria = GetCriteria(q, ConditionAlias.Less, ConditionType.Less, entityType);
         }
         else if (q.Contains(ConditionAlias.GreaterEqual, StringComparison.OrdinalIgnoreCase) && profile.IsConditionAllowed(ConditionType.GreaterEqual))
         {
             criteria = GetCriteria(q, ConditionAlias.GreaterEqual, ConditionType.GreaterEqual, entityType);
         }
         else if (q.Contains(ConditionAlias.Greater, StringComparison.OrdinalIgnoreCase) && profile.IsConditionAllowed(ConditionType.Greater))
         {
             criteria = GetCriteria(q, ConditionAlias.Greater, ConditionType.Greater, entityType);
         }
         else if (q.Contains(ConditionAlias.Contains, StringComparison.OrdinalIgnoreCase) && profile.IsConditionAllowed(ConditionType.Contains))
         {
             criteria = GetCriteria(q, ConditionAlias.Contains, ConditionType.Contains, entityType);
         }
         else if (q.Contains(ConditionAlias.StartsWith, StringComparison.OrdinalIgnoreCase) && profile.IsConditionAllowed(ConditionType.StartsWith))
         {
             criteria = GetCriteria(q, ConditionAlias.StartsWith, ConditionType.StartsWith, entityType);
         }
         else if (q.Contains(ConditionAlias.EndsWith, StringComparison.OrdinalIgnoreCase) && profile.IsConditionAllowed(ConditionType.EndsWith))
         {
             criteria = GetCriteria(q, ConditionAlias.EndsWith, ConditionType.EndsWith, entityType);
         }
         else if (q.Contains(ConditionAlias.Between, StringComparison.OrdinalIgnoreCase) && profile.IsConditionAllowed(ConditionType.Between))
         {
             criteria = GetCriteria(q, ConditionAlias.Between, ConditionType.Between, entityType);
         }
         else if (q.Contains(ConditionAlias.Equal, StringComparison.OrdinalIgnoreCase) && profile.IsConditionAllowed(ConditionType.Equal))
         {
             criteria = GetCriteria(q, ConditionAlias.Equal, ConditionType.Equal, entityType);
         }
         if (criteria != null)
         {
             yield return(criteria);
         }
     }
 }
예제 #18
0
        public static QueryResult Build <T>(IQueryable <T> query, Type entityType, Clauses clauses, IList <Criteria> criterias, AutoQueryableProfile profile, bool countAllRows) where T : class
        {
            IColumnProvider            columnProvider = ProviderFactory.GetColumnProvider(profile?.ProviderType);
            IEnumerable <SelectColumn> selectColumns  = columnProvider.GetSelectableColumns(clauses, profile, entityType);

            IEnumerable <Column> orderColumns     = OrderByHelper.GetOrderByColumns(profile, clauses.OrderBy, entityType);
            IEnumerable <Column> orderDescColumns = OrderByHelper.GetOrderByColumns(profile, clauses.OrderByDesc, entityType);

            if (criterias != null && criterias.Any())
            {
                query = query.Where(criterias);
            }
            var totalCount = 0;

            if (countAllRows)
            {
                totalCount = query.Count();
            }
            if (orderColumns != null)
            {
                query = query.OrderBy(orderColumns);
            }
            else if (orderDescColumns != null)
            {
                query = query.OrderByDesc(orderDescColumns);
            }

            IQueryable <object> queryProjection;

            if (clauses.Select == null && profile?.UnselectableProperties == null && profile?.SelectableProperties == null)
            {
                queryProjection = query;
            }
            else
            {
                if (profile.UseBaseType)
                {
                    queryProjection = query.Select(SelectHelper.GetSelector <T, T>(selectColumns, profile));
                }
                else
                {
                    queryProjection = query.Select(SelectHelper.GetSelector <T, object>(selectColumns, profile));
                }
            }

            if (clauses.Skip != null)
            {
                int.TryParse(clauses.Skip.Value, out int skip);
                if (profile?.MaxToSkip != null && skip > profile.MaxToSkip)
                {
                    skip = profile.MaxToSkip.Value;
                }
                queryProjection = queryProjection.Skip(skip);
            }
            if (clauses.Top != null)
            {
                int.TryParse(clauses.Top.Value, out int take);
                if (profile?.MaxToTake != null && take > profile?.MaxToTake)
                {
                    take = profile.MaxToTake.Value;
                }
                queryProjection = queryProjection.Take(take);
            }
            else if (clauses.First != null)
            {
                return(new QueryResult {
                    Result = queryProjection.FirstOrDefault(), TotalCount = totalCount
                });
            }
            else if (clauses.Last != null)
            {
                return(new QueryResult {
                    Result = queryProjection.LastOrDefault(), TotalCount = totalCount
                });
            }
            else if (profile?.MaxToTake != null)
            {
                queryProjection = queryProjection.Take(profile.MaxToTake.Value);
            }
            return(new QueryResult {
                Result = queryProjection, TotalCount = totalCount
            });
        }
예제 #19
0
        public IEnumerable <SelectColumn> GetSelectableColumns(Clauses clauses, AutoQueryableProfile profile, Type entityType)
        {
            if (clauses.Select == null)
            {
                IEnumerable <string> columns = GetSelectableColumns(profile, entityType);
                clauses.Select = new Clause {
                    ClauseType = ClauseType.Select, Value = string.Join(",", columns.ToArray())
                };
            }
            List <SelectColumn> allSelectColumns = new List <SelectColumn>();
            List <SelectColumn> selectColumns    = new List <SelectColumn>();
            var selection = clauses.Select.Value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()).ToList();
            var selectionWithColumnPath = new List <string[]>();

            foreach (string selectionItem in selection)
            {
                var columnPath = selectionItem.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()).ToArray();
                selectionWithColumnPath.Add(columnPath);
            }
            foreach (string[] selectionColumnPath in selectionWithColumnPath)
            {
                var parentType = entityType;
                int?maxDepth   = profile?.MaxDepth;

                for (int i = 0; i < selectionColumnPath.Length; i++)
                {
                    if (maxDepth.HasValue && i >= maxDepth.Value)
                    {
                        break;
                    }
                    string key = string.Join(".", selectionColumnPath.Take(i + 1)).ToLowerInvariant();

                    var columnName = selectionColumnPath[i];
                    var property   = parentType.GetProperties().FirstOrDefault(x => x.Name.ToLowerInvariant() == columnName.ToLowerInvariant());
                    if (property == null)
                    {
                        if (key.EndsWith(".*") && (!maxDepth.HasValue || (i < maxDepth - 1)))
                        {
                            var inclusionColumn = allSelectColumns.FirstOrDefault(all => all.Key == key.Replace(".*", ""));
                            inclusionColumn.InclusionType = SelectInclusingType.IncludeAllProperties;
                        }
                        break;
                    }
                    bool isCollection = property.PropertyType.IsEnumerableButNotString();
                    // Max depth & collection or object
                    if (maxDepth.HasValue && (i >= maxDepth - 1) && (isCollection || property.PropertyType.IsCustomObjectType()))
                    {
                        continue;
                    }
                    if (isCollection)
                    {
                        parentType = property.PropertyType.GetGenericArguments().FirstOrDefault();
                    }
                    else
                    {
                        parentType = property.PropertyType;
                    }
                    SelectColumn column = allSelectColumns.FirstOrDefault(all => all.Key == key);
                    if (column == null)
                    {
                        // pass non selectable properties
                        if (profile?.SelectableProperties != null && !profile.SelectableProperties.Contains(key, StringComparer.OrdinalIgnoreCase))
                        {
                            continue;
                        }
                        // pass unselectable properties
                        if (profile?.UnselectableProperties != null && profile.UnselectableProperties.Contains(key, StringComparer.OrdinalIgnoreCase))
                        {
                            continue;
                        }
                        column = new SelectColumn
                        {
                            Key        = key,
                            Name       = columnName,
                            SubColumns = new List <SelectColumn>(),
                            Type       = property.PropertyType
                        };
                        allSelectColumns.Add(column);
                        if (i == 0)
                        {
                            selectColumns.Add(column);
                        }
                        else
                        {
                            string       parentKey    = string.Join(".", selectionColumnPath.Take(i)).ToLowerInvariant();
                            SelectColumn parentColumn = allSelectColumns.FirstOrDefault(all => all.Key == parentKey);
                            if (selection.Contains(parentKey + ".*", StringComparer.OrdinalIgnoreCase))
                            {
                                parentColumn.InclusionType = SelectInclusingType.IncludeAllProperties;
                            }
                            else if (selection.Contains(parentKey, StringComparer.OrdinalIgnoreCase))
                            {
                                parentColumn.InclusionType = SelectInclusingType.IncludeBaseProperties;
                            }

                            column.ParentColumn = parentColumn;
                            parentColumn.SubColumns.Add(column);
                        }
                    }
                }
            }
            ProcessInclusingType(profile, selectColumns);

            return(selectColumns);
        }
예제 #20
0
 public IEnumerable <WrapperPartType> GetWrapperParts(string[] queryStringWrapperParts, AutoQueryableProfile profile)
 {
     foreach (string q in queryStringWrapperParts)
     {
         if (q.Equals(WrapperAlias.Count, StringComparison.OrdinalIgnoreCase) && profile.IsWrapperPartAllowed(WrapperPartType.Count))
         {
             yield return(WrapperPartType.Count);
         }
         else if (q.Equals(WrapperAlias.NextLink, StringComparison.OrdinalIgnoreCase) && profile.IsWrapperPartAllowed(WrapperPartType.NextLink))
         {
             yield return(WrapperPartType.NextLink);
         }
         else if (q.Equals(WrapperAlias.TotalCount, StringComparison.OrdinalIgnoreCase) && profile.IsWrapperPartAllowed(WrapperPartType.TotalCount))
         {
             yield return(WrapperPartType.TotalCount);
         }
     }
 }
예제 #21
0
        public IEnumerable <SelectColumn> GetSelectableColumns(Clauses clauses, AutoQueryableProfile profile, Type entityType)
        {
            List <SelectColumn> selectColumns = new List <SelectColumn>();

            // If select clause is null, take all properties.
            if (clauses.Select == null)
            {
                IEnumerable <SelectColumn> entityColumns = EntityColumnHelper.GetSelectableColumns(profile, entityType);
                selectColumns.AddRange(entityColumns);
            }
            else
            {
                string[] uriPropertyNames = clauses.Select.Value.Split(',');
                foreach (string n in uriPropertyNames)
                {
                    // remove properties who does not exist on the entity type
                    PropertyInfo property = entityType.GetProperties().FirstOrDefault(x =>
                                                                                      string.Equals(x.Name, n, StringComparison.OrdinalIgnoreCase));
                    if (property == null)
                    {
                        continue;
                    }

                    // Remove non selectable properties.
                    if (profile?.SelectableProperties != null)
                    {
                        if (!profile.SelectableProperties.Contains(n, StringComparer.OrdinalIgnoreCase))
                        {
                            continue;
                        }
                    }

                    // Remove unselectable properties.
                    if (profile?.UnselectableProperties != null)
                    {
                        if (profile.UnselectableProperties.Contains(n, StringComparer.OrdinalIgnoreCase))
                        {
                            continue;
                        }
                    }
                    selectColumns.Add(new SelectColumn
                    {
                        Key  = n,
                        Name = n,
                        Type = property.PropertyType
                    });
                }
            }

            // Nothing to expand, return values directly.
            if (clauses.Expand == null)
            {
                //foreach (string s in clauses.Expand.Value.Split(','))
                //{
                //    PropertyInfo property = entityType.GetProperties().FirstOrDefault(x => string.Equals(x.Name, s, StringComparison.OrdinalIgnoreCase));
                //    if (property == null) continue;

                //    selectColumns.Add(new SelectColumn
                //    {
                //        Key = s,
                //        Name = s,
                //        Type = property.PropertyType
                //    });
                //}
                return(selectColumns);
            }

            return(selectColumns);
        }