public virtual WrappedResponse <PagedList <DTO> > List(GenericPagedFilter query)
        {
            var predicate = PredicateBuilder.False <TEntity>();

            ParameterExpression argParam = Expression.Parameter(typeof(TEntity), "x");


            Filter normalized = new Filter();

            normalized.Inner = query.Filter;

            Expression andExp = default(Expression);

            if (query != null && query.Filter != null && query.Filter.Count > 0)
            {
                andExp = RecursiveAddFilter(normalized, argParam, andExp);
            }
            else
            {
                andExp = Expression.Equal(Expression.Constant(true), Expression.Constant(true));
            }

            var lambda = Expression.Lambda <Func <TEntity, bool> >(andExp, argParam);


            var orderbyList = new List <OrderInfo <TEntity> >();

            if (query != null && query.OrderBy != null)
            {
                foreach (var order in query.OrderBy)
                {
                    // check if order is valid
                    MemberExpression nameProperty = null;
                    try
                    {
                        nameProperty = Expression.Property(argParam, order.Name);
                        orderbyList.Add(
                            new OrderInfo <TEntity>()
                        {
                            KeySelector = nameProperty,
                            Direction   = order.Direction
                        }
                            );
                    }
                    catch (Exception e)
                    {
                        //logger.Warn($"Order error: field not valid: {e.Message}");
                        MessageService.AddWarning($"Order error: field not valid: {e.Message}", UiMessageTarget.TOAST, "Filter Parser", "SFW_102", order.Name);
                    }
                }

                //orderbyList.Add(
                //    new OrderInfo<TEntity>((x) => x.Id, OrderByDirection.DESC)
                //    );
            }
            return(WrappedOK(Service.List(lambda, query.PageNumber, query.PageSize, orderbyList)));
        }
        private Expression  GetQueryClause(ParameterExpression argParam, Filter filter)
        {
            MemberExpression nameProperty = null;

            try
            {
                nameProperty = Expression.Property(argParam, filter.Name);
            }
            catch (Exception e)
            {
                //logger.Warn($"Filter error: field not valid: {e.Message}");
                MessageService.AddWarning($"Filter error: field not valid: {e.Message}", UiMessageTarget.TOAST, "Filter Parser", "SFW_101", filter.Name);
                return(null);
            }


            object typedValue = null;

            var value = Expression.Constant("");

            if (filter.Comparator != QueryComparator.In)
            {
                typedValue = ConversionHelper.StringToObject(filter.Value, nameProperty.Type);

                value = Expression.Constant(typedValue, nameProperty.Type);
            }

            Expression clause = null;

            switch (filter.Comparator)
            {
            case QueryComparator.Equal:
                clause = Expression.Equal(nameProperty, value);
                break;

            case QueryComparator.Greater:
                clause = Expression.GreaterThan(nameProperty, value);
                break;

            case QueryComparator.Lower:
                clause = Expression.LessThan(nameProperty, value);
                break;

            case QueryComparator.Contains:

                // Contains
                var        propertyExp = Expression.Property(argParam, filter.Name);
                MethodInfo method      = typeof(string).GetMethod("Contains", new Type[] { typeof(string) });
                //var constant = Expression.Constant(value.Value, typeof(string));
                clause = Expression.Call(propertyExp, method, Expression.Constant(value.Value));
                break;

            case QueryComparator.In:
                // Contains
                var propertyExp2 = Expression.Property(argParam, filter.Name);

                string filterValues = filter.Value;

                if (!filterValues.StartsWith("["))
                {
                    filterValues = String.Concat("[", filterValues);
                }

                if (!filterValues.EndsWith("]"))
                {
                    filterValues = String.Concat(filterValues, "]");
                }

                var values = JArray.Parse(filterValues);

                var listType     = typeof(List <>).MakeGenericType(nameProperty.Type);
                var listInstance = Activator.CreateInstance(listType);

                var addmethod = listType.GetMethod("Add");
                foreach (var val in values)
                {
                    var typedVal = val.ToObject(nameProperty.Type);
                    addmethod.Invoke(listInstance, new object[] { typedVal });
                }

                MethodInfo method2 = listType.GetMethod("Contains", new Type[] { nameProperty.Type });
                clause = Expression.Call(Expression.Constant(listInstance), method2, propertyExp2);

                break;

            default:
                break;
            }

            return(clause);
        }