예제 #1
0
        /// <summary>
        /// Get expression for <see cref="FilterType.In"/> filter
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="filterItem"></param>
        /// <param name="paramSelector"></param>
        /// <param name="datatypeFunc"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentException">If no collection available</exception>
        public static Expression <Func <TModel, bool> > CollectionExpression <TModel, TValue>(
            this FilterItemModel filterItem,
            Expression <Func <TModel, TValue> > paramSelector,
            Func <object, TValue> datatypeFunc)
            where TModel : class
        {
            if (!CollectionHelper.IsEnumerableObject(filterItem.Value))
            {
                throw new ArgumentException("'In' filter needs a collection as a value.");
            }

            var collection = CollectionHelper.EnumerableObjectToList(filterItem.Value, datatypeFunc);

            if (!collection.Any())
            {
                throw new ArgumentException("'In' filter needs a collection as a value.");
            }

            if (collection.Count == 1)
            {
                filterItem.Value  = collection[0];
                filterItem.Filter = FilterType.Equal;

                return(null);
            }

            var datatypeParamSelector = CollectionHelper.GetCollectionFilterExpression(collection);

            return(paramSelector.CombineSelectorParamExpression(datatypeParamSelector));
        }
예제 #2
0
        public static Expression <Func <TModel, bool> > ToExpression <TModel>(FilterItemModel filterItem)
            where TModel : class
        {
            var isNullable = ReflectionHelper.IsNullable <TModel>(filterItem.Column);

            return(ToSingleValueExpression <TModel>(filterItem, isNullable));
        }
예제 #3
0
        private static FilterModel GetFilter()
        {
            var sort       = new SortModel("Id", 1, 3);
            var filterItem = new FilterItemModel("Id", ColumnType.GuidColumn, FilterType.NotEqual, Guid.NewGuid());

            return(new FilterModel(sort, filterItem));
        }
예제 #4
0
        public void GetCollectionExpressionSingleTest()
        {
            var filter = new FilterItemModel(nameof(DataModel.DataInt), ColumnType.IntColumn, FilterType.In, new List <object> {
                1
            });
            Expression <Func <DataModel, int> > paramSelector = x => x.DataInt;

            int DataTypeFunc(object x) => (int)x;

            var expression = filter.CollectionExpression(paramSelector, DataTypeFunc);

            Assert.Null(expression);
        }
예제 #5
0
        public void GetExpressionStringTest(string columnName, ColumnType columnType, FilterType filterType, object valueTrue, object valueFalse)
        {
            var filterTrue      = new FilterItemModel(columnName, columnType, filterType, valueTrue);
            var filterFalse     = new FilterItemModel(columnName, columnType, filterType, valueFalse);
            var expressionTrue  = FilterItemHelper.ToExpression <DataModel>(filterTrue);
            var expressionFalse = FilterItemHelper.ToExpression <DataModel>(filterFalse);
            var models          = new List <DataModel> {
                Model
            };

            Assert.Single(models.Where(expressionTrue.Compile()));
            Assert.Empty(models.Where(expressionFalse.Compile()));
        }
예제 #6
0
        public void GetCollectionExpressionThrowsTest()
        {
            Expression <Func <DataModel, int> > paramSelector = x => x.DataInt;

            int DataTypeFunc(object x) => (int)x;

            var filter = new FilterItemModel(nameof(DataModel.DataInt), ColumnType.IntColumn, new List <object>());

            Assert.Throws <ArgumentException>(() => filter.CollectionExpression(paramSelector, DataTypeFunc));

            filter = new FilterItemModel(nameof(DataModel.DataInt), ColumnType.IntColumn, FilterType.In, 2);
            Assert.Throws <ArgumentException>(() => filter.CollectionExpression(paramSelector, DataTypeFunc));
        }
예제 #7
0
        public static Expression <Func <TModel, bool> > EnumToExpression <TModel>(this FilterItemModel filterItem, Type typeEnum)
            where TModel : class
        {
            var isNullable                 = ReflectionHelper.IsNullable <TModel>(filterItem.Column);
            var propertyType               = isNullable ? typeof(int?) : typeof(int);
            var paramExpression            = Expression.Parameter(typeof(TModel));
            var propertySelector           = filterItem.Column.Split('.').Aggregate <string, Expression>(paramExpression, Expression.Property);
            var castedPropertySelector     = Expression.Convert(propertySelector, propertyType);
            var compareExpression          = Expression.Constant(IntHelper.ToIntOrNull(filterItem.Value));
            var convertedCompareExpression = Expression.Convert(compareExpression, propertyType);
            var bodyExpression             = Expression.Equal(castedPropertySelector, convertedCompareExpression);
            var expression                 = Expression.Lambda <Func <TModel, bool> >(bodyExpression, paramExpression);

            return(expression);
        }
예제 #8
0
        public void GetCollectionExpressionCollectionTest()
        {
            var filter = new FilterItemModel(nameof(DataModel.DataInt), ColumnType.IntColumn, new List <object> {
                1, 2, 3
            });
            Expression <Func <DataModel, int> > paramSelector = x => x.DataInt;

            int DataTypeFunc(object x) => (int)x;

            var expression = filter.CollectionExpression(paramSelector, DataTypeFunc);

            Assert.NotNull(expression);

            var models = new List <DataModel> {
                Model
            };

            Assert.Single(models.Where(expression.Compile()));
        }
예제 #9
0
        private static Expression <Func <TModel, bool> > ToStringValueExpression <TModel>(FilterItemModel filterItem)
            where TModel : class
        {
            if (string.IsNullOrWhiteSpace(filterItem.Value.ToString()))
            {
                throw new ArgumentException($"{filterItem.Value} is not of type {typeof(string)}.");
            }

            var filterValue = filterItem.Value.ToString();

            var entityParamSelector = ReflectionHelper.MemberSelector <TModel, string>(filterItem.Column);

            if (filterItem.Filter == FilterType.In)
            {
                var result = filterItem.CollectionExpression(entityParamSelector, x => x.ToString());
                if (result != null)
                {
                    return(result);
                }
            }

            var expression = FilterExpressionHelper.GetExpression(filterItem.Filter, filterValue);

            return(entityParamSelector.CombineSelectorParamExpression(expression));
        }
예제 #10
0
        private static Expression <Func <TModel, bool> > ToDateTimeOffsetValueExpression <TModel>(FilterItemModel filterItem, bool isNullable)
            where TModel : class
        {
            var nullableFilterValue = DateTimeOffsetHelper.ToDateTimeOffsetOrNull(filterItem.Value);

            if (!nullableFilterValue.HasValue || DateTimeOffsetHelper.DateTimeOffsetIsNullOrEmpty(nullableFilterValue))
            {
                throw new ArgumentException($"{filterItem.Value} is not of type {typeof(DateTimeOffset)}.");
            }

            var filterValue = nullableFilterValue.Value;

            if (isNullable)
            {
                var entityParamSelector = ReflectionHelper.MemberSelector <TModel, DateTimeOffset?>(filterItem.Column);
                if (filterItem.Filter == FilterType.In)
                {
                    var result = filterItem.CollectionExpression(entityParamSelector, DateTimeOffsetHelper.ToDateTimeOffsetOrNull);
                    if (result != null)
                    {
                        return(result);
                    }
                }

                var expression = FilterExpressionHelper.GetNullableExpression(filterItem.Filter, filterValue);

                return(entityParamSelector.CombineSelectorParamExpression(expression));
            }
            else
            {
                var entityParamSelector = ReflectionHelper.MemberSelector <TModel, DateTimeOffset>(filterItem.Column);
                if (filterItem.Filter == FilterType.In)
                {
                    var result = filterItem.CollectionExpression(entityParamSelector, DateTimeOffsetHelper.ToDateTimeOffset);
                    if (result != null)
                    {
                        return(result);
                    }
                }

                var expression = FilterExpressionHelper.GetExpression(filterItem.Filter, filterValue);

                return(entityParamSelector.CombineSelectorParamExpression(expression));
            }
        }
예제 #11
0
        private static Expression <Func <TModel, bool> > ToIntValueExpression <TModel>(FilterItemModel filterItem, bool isNullable)
            where TModel : class
        {
            var type = ReflectionHelper.GetPropertyType <TModel>(filterItem.Column);

            if (type.IsEnum || type.IsNullableEnum())
            {
                if (filterItem.Filter == FilterType.Equal)
                {
                    return(EnumToExpression <TModel>(filterItem, type));
                }

                throw new ArgumentException($"Filter {filterItem.Filter} not supported for type Enum. Only {FilterType.Equal} kan be evaluated.", nameof(filterItem));
            }

            var nullableFilterValue = IntHelper.ToIntOrNull(filterItem.Value);

            if (!nullableFilterValue.HasValue)
            {
                throw new ArgumentException($"{filterItem.Value} is not of type {typeof(int)}.");
            }

            var filterValue = nullableFilterValue.Value;

            if (isNullable)
            {
                var entityParamSelector = ReflectionHelper.MemberSelector <TModel, int?>(filterItem.Column);

                if (filterItem.Filter == FilterType.In)
                {
                    var result = filterItem.CollectionExpression(entityParamSelector, IntHelper.ToIntOrNull);
                    if (result != null)
                    {
                        return(result);
                    }
                }

                var expression = FilterExpressionHelper.GetNullableExpression(filterItem.Filter, filterValue);

                return(entityParamSelector.CombineSelectorParamExpression(expression));
            }
            else
            {
                var entityParamSelector = ReflectionHelper.MemberSelector <TModel, int>(filterItem.Column);

                if (filterItem.Filter == FilterType.In)
                {
                    var result = filterItem.CollectionExpression(entityParamSelector, IntHelper.ToInt);
                    if (result != null)
                    {
                        return(result);
                    }
                }

                var expression = FilterExpressionHelper.GetExpression(filterItem.Filter, filterValue);

                return(entityParamSelector.CombineSelectorParamExpression(expression));
            }
        }
예제 #12
0
        private static Expression <Func <TModel, bool> > ToSingleValueExpression <TModel>(FilterItemModel filterItem, bool isNullable)
            where TModel : class
        {
            switch (filterItem.Type)
            {
            case ColumnType.StringColumn:
                return(ToStringValueExpression <TModel>(filterItem));

            case ColumnType.GuidColumn:
                return(ToGuidValueExpression <TModel>(filterItem, isNullable));

            case ColumnType.BoolColumn:
                return(ToBoolValueExpression <TModel>(filterItem, isNullable));

            case ColumnType.DateTimeOffsetColumn:
                return(ToDateTimeOffsetValueExpression <TModel>(filterItem, isNullable));

            case ColumnType.IntColumn:
                return(ToIntValueExpression <TModel>(filterItem, isNullable));

            case ColumnType.DoubleColumn:
                return(ToDoubleValueExpression <TModel>(filterItem, isNullable));

            default:
                throw new ArgumentOutOfRangeException($"{nameof(ColumnType)} {filterItem.Type} is not supported.", nameof(filterItem));
            }
        }
예제 #13
0
        private static Expression <Func <TModel, bool> > ToBoolValueExpression <TModel>(FilterItemModel filterItem, bool isNullable)
            where TModel : class
        {
            var nullableFilterValue = BoolHelper.ToBoolOrNull(filterItem.Value);

            if (!nullableFilterValue.HasValue)
            {
                throw new ArgumentException($"{filterItem.Value} is not of type {typeof(bool)}.");
            }

            var filterValue = nullableFilterValue.Value;

            if (isNullable)
            {
                var entityParamSelector = ReflectionHelper.MemberSelector <TModel, bool?>(filterItem.Column);
                var expression          = FilterExpressionHelper.GetNullableExpression(filterItem.Filter, filterValue);

                return(entityParamSelector.CombineSelectorParamExpression(expression));
            }
            else
            {
                var entityParamSelector = ReflectionHelper.MemberSelector <TModel, bool>(filterItem.Column);
                var expression          = FilterExpressionHelper.GetExpression(filterItem.Filter, filterValue);

                return(entityParamSelector.CombineSelectorParamExpression(expression));
            }
        }