public List <Expression <Func <T, bool> > > BuildPredicate <T>(PropertyFilterConfig propertyFilterConfig)
        {
            var parameterExpression = Expression.Parameter(typeof(T), typeof(T).Name);

            return(BuildNavigationExpression <T>(parameterExpression, propertyFilterConfig)
                   .Cast <Expression <Func <T, bool> > >()
                   .ToList());
        }
        private static Expression BuildCondition(Expression parameter, PropertyFilterConfig propertyFilterConfig)
        {
            var childProperty = parameter.Type.GetProperty(propertyFilterConfig.PropertyName);
            var left          = Expression.Property(parameter, childProperty);
            var right         = Expression.Constant(propertyFilterConfig.Value);
            var predicate     = BuildComparsion(left, propertyFilterConfig.OperatorComparer.Value, right);

            return(MakeLambda(parameter, predicate));
        }
Beispiel #3
0
        public List <IReSort <School> > GetSorters(PropertyFilterConfig propertyFilterConfig)
        {
            List <IReSort <School> > sorters = new List <IReSort <School> >();

            if (propertyFilterConfig != null)
            {
                if (propertyFilterConfig.PropertyName == nameof(SchoolFilterRequest.Country))
                {
                    sorters.Add(new CountrySorter());
                }
            }

            return(sorters);
        }
        private static Expression BuildNavigationExpression(Expression parameter, PropertyFilterConfig propertyFilterConfig)
        {
            var isCollection = typeof(IEnumerable).IsAssignableFrom(parameter.Type);

            //if it´s a collection we later need to use the predicate in the methodexpressioncall
            if (isCollection)
            {
                var childType      = parameter.Type.GetGenericArguments()[0];
                var childParameter = Expression.Parameter(childType, childType.Name);
                var newPredicate   = BuildNavigationExpression(childParameter, propertyFilterConfig);

                return(BuildSubQuery(childParameter, childType, newPredicate));
            }

            return(BuildCondition(parameter, propertyFilterConfig));
        }
        public PropertyInfo GetChildProperty(Expression parameter, PropertyFilterConfig propertyFilterConfig)
        {
            var sameNameProperties = parameter.Type.GetProperties()
                                     .Where(p => p.Name == propertyFilterConfig.PropertyName)
                                     .ToList();

            if (sameNameProperties.Any() && sameNameProperties.Count > 1)
            {
                var declaringTypeName = parameter.Type.Name;
                var childProperties   = parameter.Type.GetProperties()
                                        .Where(e => e.DeclaringType.Name == declaringTypeName)
                                        .ToList();

                return(childProperties.FirstOrDefault());
            }
            else
            {
                return(sameNameProperties.FirstOrDefault());
            }
        }
        public static Expression <Func <T, bool> > BuildPredicate <T>(PropertyFilterConfig propertyFilterConfig)
        {
            var parameterExpression = Expression.Parameter(typeof(T), typeof(T).Name);

            return((Expression <Func <T, bool> >)BuildNavigationExpression(parameterExpression, propertyFilterConfig));
        }
        private List <Expression> BuildNavigationExpression <T>(Expression parameter, PropertyFilterConfig propertyFilterConfig)
        {
            PropertyInfo childProperty = GetChildProperty(parameter, propertyFilterConfig);

            if ((!childProperty.PropertyType.IsByRef && !childProperty.PropertyType.IsClass) ||
                childProperty.PropertyType.IsValueType || childProperty.PropertyType.Name == "String")
            {
                // Meant to handle all strings and similar simple stuff
                return(new List <Expression> {
                    BuildCondition <T>(parameter, propertyFilterConfig)
                });
            }
            else if (childProperty.PropertyType.IsClass && !typeof(IEnumerable).IsAssignableFrom(childProperty.PropertyType))
            {
                // Meant to handle Recursive Search
                List <PropertyInfo> searchableProperties = childProperty.PropertyType.GetSearchableProperties();
                if (searchableProperties.Any())
                {
                    // This is key for recursion
                    var childParameter = Expression.Property(parameter, childProperty);
                    var expressions    = new List <Expression>();
                    searchableProperties.ForEach(e =>
                    {
                        var newPropertyFilterConfig = BuildSearchPropertyFilterConfig(e, (string)propertyFilterConfig.Value);
                        expressions.AddRange(BuildNavigationExpression <T>(childParameter, newPropertyFilterConfig));
                    });

                    return(expressions);
                }
                else
                {
                    return(new List <Expression>());
                }
            }
            else if (typeof(IEnumerable).IsAssignableFrom(childProperty.PropertyType))
            {
                // if it´s a collection we later need to use the predicate in the methodexpressioncall
                var childType = childProperty.PropertyType.GenericTypeArguments[0];
                List <PropertyInfo> searchableProperties = childType.GetSearchableProperties();

                if (searchableProperties.Any())
                {
                    // This is key for recursion
                    var childParameterStandalone = Expression.Parameter(childType, childType.Name);
                    var childParameter           = Expression.Property(parameter, childProperty);
                    var subExpressions           = new List <Expression>();

                    var childBuilderMethod = typeof(ReFilterExpressionBuilder).GetMethod(nameof(BuildNavigationExpression), BindingFlags.NonPublic | BindingFlags.Instance);
                    var childNavigationExpressionBuilder = childBuilderMethod.MakeGenericMethod(childType);
                    var newInstance = Expression.New(typeof(ReFilterExpressionBuilder));

                    searchableProperties.ForEach(e =>
                    {
                        var newPropertyFilterConfig = BuildSearchPropertyFilterConfig(e, (string)propertyFilterConfig.Value);
                        var methodCallExpression    = Expression.Call(newInstance, childNavigationExpressionBuilder,
                                                                      Expression.Constant(childParameterStandalone), Expression.Constant(newPropertyFilterConfig));
                        subExpressions.AddRange(Expression.Lambda <Func <List <Expression> > >(methodCallExpression).Compile()());
                    });

                    var childExpressions           = new List <Expression>();
                    var childSubQueryBuilderMethod = typeof(ReFilterExpressionBuilder).GetMethod(nameof(BuildSubQuery), BindingFlags.NonPublic | BindingFlags.Instance);
                    var childSubQueryBuilder       = childSubQueryBuilderMethod.MakeGenericMethod(childType);

                    subExpressions.ForEach(subExpression =>
                    {
                        childExpressions.AddRange(BuildSubQuery <T>(childParameter, childType, subExpression));
                    });

                    return(childExpressions);
                }
                else
                {
                    return(new List <Expression>());
                }
            }
            else
            {
                return(new List <Expression> {
                    BuildCondition <T>(parameter, propertyFilterConfig)
                });
            }
        }
Beispiel #8
0
        public IOrderedQueryable <School> BuildSortedQuery(IQueryable <School> query, PropertyFilterConfig propertyFilterConfig,
                                                           bool isFirst = false)
        {
            var sorters = GetSorters(propertyFilterConfig);

            if (sorters == null || sorters.Count == 0)
            {
                return((IOrderedQueryable <School>)query);
            }

            IOrderedQueryable <School> orderedQuery = (IOrderedQueryable <School>)query;

            for (var i = 0; i < sorters.Count; i++)
            {
                orderedQuery = sorters[i].SortQuery(orderedQuery,
                                                    propertyFilterConfig.SortDirection.Value,
                                                    isFirst: (i == 0 && isFirst));
            }

            return(orderedQuery);
        }
Beispiel #9
0
        public List <PropertyFilterConfig> UnpackRangeFilter <U>(RangeFilter <U> rangeFilter, PropertyFilterConfig selectedPfc) where U : struct
        {
            var newPropertyFilterConfigs = new List <PropertyFilterConfig>();

            var lowValue  = rangeFilter.Start;
            var highValue = rangeFilter.End;

            switch (selectedPfc.OperatorComparer)
            {
            case OperatorComparer.Equals:
                newPropertyFilterConfigs.Add(new PropertyFilterConfig
                {
                    OperatorComparer = OperatorComparer.LessThanOrEqual,
                    PropertyName     = selectedPfc.PropertyName,
                    Value            = lowValue ?? highValue
                });

                newPropertyFilterConfigs.Add(new PropertyFilterConfig
                {
                    OperatorComparer = OperatorComparer.GreaterThanOrEqual,
                    PropertyName     = selectedPfc.PropertyName,
                    Value            = lowValue ?? highValue
                });
                break;

            case OperatorComparer.BetweenExclusive:
                if (lowValue != null)
                {
                    newPropertyFilterConfigs.Add(new PropertyFilterConfig
                    {
                        OperatorComparer = OperatorComparer.GreaterThan,
                        PropertyName     = selectedPfc.PropertyName,
                        Value            = lowValue
                    });
                }

                if (highValue != null)
                {
                    newPropertyFilterConfigs.Add(new PropertyFilterConfig
                    {
                        OperatorComparer = OperatorComparer.LessThan,
                        PropertyName     = selectedPfc.PropertyName,
                        Value            = highValue
                    });
                }
                break;

            case OperatorComparer.BetweenInclusive:
                if (lowValue != null)
                {
                    newPropertyFilterConfigs.Add(new PropertyFilterConfig
                    {
                        OperatorComparer = OperatorComparer.GreaterThanOrEqual,
                        PropertyName     = selectedPfc.PropertyName,
                        Value            = lowValue
                    });
                }

                if (highValue != null)
                {
                    newPropertyFilterConfigs.Add(new PropertyFilterConfig
                    {
                        OperatorComparer = OperatorComparer.LessThanOrEqual,
                        PropertyName     = selectedPfc.PropertyName,
                        Value            = highValue
                    });
                }
                break;

            case OperatorComparer.BetweenHigherInclusive:
                if (lowValue != null)
                {
                    newPropertyFilterConfigs.Add(new PropertyFilterConfig
                    {
                        OperatorComparer = OperatorComparer.GreaterThan,
                        PropertyName     = selectedPfc.PropertyName,
                        Value            = lowValue
                    });
                }

                if (highValue != null)
                {
                    newPropertyFilterConfigs.Add(new PropertyFilterConfig
                    {
                        OperatorComparer = OperatorComparer.LessThanOrEqual,
                        PropertyName     = selectedPfc.PropertyName,
                        Value            = highValue
                    });
                }
                break;

            case OperatorComparer.BetweenLowerInclusive:
                if (lowValue != null)
                {
                    newPropertyFilterConfigs.Add(new PropertyFilterConfig
                    {
                        OperatorComparer = OperatorComparer.GreaterThanOrEqual,
                        PropertyName     = selectedPfc.PropertyName,
                        Value            = lowValue
                    });
                }

                if (highValue != null)
                {
                    newPropertyFilterConfigs.Add(new PropertyFilterConfig
                    {
                        OperatorComparer = OperatorComparer.LessThan,
                        PropertyName     = selectedPfc.PropertyName,
                        Value            = highValue
                    });
                }
                break;

            case OperatorComparer.LessThan:
                newPropertyFilterConfigs.Add(new PropertyFilterConfig
                {
                    OperatorComparer = selectedPfc.OperatorComparer,
                    PropertyName     = selectedPfc.PropertyName,
                    Value            = lowValue ?? highValue
                });
                break;

            case OperatorComparer.LessThanOrEqual:
                newPropertyFilterConfigs.Add(new PropertyFilterConfig
                {
                    OperatorComparer = selectedPfc.OperatorComparer,
                    PropertyName     = selectedPfc.PropertyName,
                    Value            = lowValue ?? highValue
                });
                break;

            case OperatorComparer.GreaterThan:
                newPropertyFilterConfigs.Add(new PropertyFilterConfig
                {
                    OperatorComparer = selectedPfc.OperatorComparer,
                    PropertyName     = selectedPfc.PropertyName,
                    Value            = lowValue ?? highValue
                });
                break;

            case OperatorComparer.GreaterThanOrEqual:
                newPropertyFilterConfigs.Add(new PropertyFilterConfig
                {
                    OperatorComparer = selectedPfc.OperatorComparer,
                    PropertyName     = selectedPfc.PropertyName,
                    Value            = lowValue ?? highValue
                });
                break;

            default:
                if (lowValue != null)
                {
                    newPropertyFilterConfigs.Add(new PropertyFilterConfig
                    {
                        OperatorComparer = OperatorComparer.GreaterThan,
                        PropertyName     = selectedPfc.PropertyName,
                        Value            = lowValue
                    });
                }

                if (highValue != null)
                {
                    newPropertyFilterConfigs.Add(new PropertyFilterConfig
                    {
                        OperatorComparer = OperatorComparer.LessThan,
                        PropertyName     = selectedPfc.PropertyName,
                        Value            = highValue
                    });
                }
                break;
            }

            return(newPropertyFilterConfigs);
        }