コード例 #1
0
        private static IEnumerable <EntityPropertyFilter> GenerateEntityPropertyFilters(ICollection <PropertyInfo> propertyInfos, string parentPropertyName)
        {
            var result = new List <EntityPropertyFilter>();
            var domainEntitiesNameSpace = typeof(Entity <>).Namespace;
            var nativeProperties        = propertyInfos.Where(p => p.PropertyType.Namespace != domainEntitiesNameSpace &&
                                                              !p.Name.EndsWith("Id"));

            foreach (var propertyInfo in nativeProperties)
            {
                var propertyName = !string.IsNullOrEmpty(parentPropertyName)
                                       ? $"{parentPropertyName}.{propertyInfo.Name}"
                                       : propertyInfo.Name;
                var entityPropertyFilter = new EntityPropertyFilter
                {
                    Name      = propertyName,
                    ValueType = propertyInfo.PropertyType
                };

                result.Add(entityPropertyFilter);
            }

            var entityProperties = propertyInfos.Where(propertyInfo => propertyInfo.PropertyType.Namespace == domainEntitiesNameSpace &&
                                                       !propertyInfo.Name.EndsWith("Id"));

            foreach (var propertyInfo in entityProperties)
            {
                var nextParentPropertyName = !string.IsNullOrEmpty(parentPropertyName)
                                                 ? $"{parentPropertyName}.{propertyInfo.Name}"
                                                 : propertyInfo.Name;
                var nextPropertyInfos = propertyInfo.PropertyType.GetProperties();
                var nextResult        = GenerateEntityPropertyFilters(nextPropertyInfos, nextParentPropertyName);

                result.AddRange(nextResult);
            }

            return(result);
        }
コード例 #2
0
        private static Expression <Func <TEntity, bool> > Express(EntityPropertyFilter entityPropertyFilter)
        {
            var entityParameter          = Expression.Parameter(typeof(TEntity), typeof(TEntity).Name.ToCamelCase());
            var entityPropertyExpression = NestedExpressionProperty(entityParameter, entityPropertyFilter.Name);

            if (entityPropertyFilter.Values == null)
            {
                var message = $"Values property cannot be null for PropertyFilter with Id: '{entityPropertyFilter.Id}'";
                throw new ArgumentException(message);
            }
            if (!entityPropertyFilter.Values.Any())
            {
                var message = $"Values property cannot be empty for PropertyFilter with Id: '{entityPropertyFilter.Id}'";
                throw new ArgumentException(message);
            }

            ConstantExpression valuesExpression;
            ConstantExpression firstValueExpression;
            ConstantExpression secondValueExpression;

            if (entityPropertyFilter.ValueType == typeof(int))
            {
                var values = entityPropertyFilter.Values.ConvertAllToInt().ToArray();
                valuesExpression      = Expression.Constant(values, values.GetType());
                firstValueExpression  = Expression.Constant(values.First(), entityPropertyFilter.ValueType);
                secondValueExpression = (values.Length > 1) ? Expression.Constant(values.Skip(1).First(), entityPropertyFilter.ValueType) : null;
            }
            else if (entityPropertyFilter.ValueType == typeof(DateTime))
            {
                var values = entityPropertyFilter.Values.ConvertAllToDateTime().ToArray();
                valuesExpression      = Expression.Constant(values, values.GetType());
                firstValueExpression  = Expression.Constant(values.First(), entityPropertyFilter.ValueType);
                secondValueExpression = (values.Length > 1) ? Expression.Constant(values.Skip(1).First(), entityPropertyFilter.ValueType) : null;
            }
            else if (entityPropertyFilter.ValueType == typeof(Double))
            {
                var values = entityPropertyFilter.Values.ConvertAllToDouble().ToArray();
                valuesExpression      = Expression.Constant(values, values.GetType());
                firstValueExpression  = Expression.Constant(values.First(), entityPropertyFilter.ValueType);
                secondValueExpression = (values.Length > 1) ? Expression.Constant(values.Skip(1).First(), entityPropertyFilter.ValueType) : null;
            }
            else if (entityPropertyFilter.ValueType == typeof(string))
            {
                valuesExpression      = Expression.Constant(entityPropertyFilter.Values, entityPropertyFilter.Values.GetType());
                firstValueExpression  = Expression.Constant(entityPropertyFilter.Values.First(), entityPropertyFilter.ValueType);
                secondValueExpression = (entityPropertyFilter.Values.Count > 1) ? Expression.Constant(entityPropertyFilter.Values.Skip(1).First(), entityPropertyFilter.ValueType) : null;
            }
            else
            {
                var message = $"An implementation for ValueType of '{entityPropertyFilter.ValueType}' has not been found for PropertyFilter with Id: '{entityPropertyFilter.Id}'.";
                throw new NotImplementedException(message);
            }

            var stringStartsWithMethodInfo   = typeof(string).GetMethod("StartsWith", new[] { typeof(string) });
            var stringContainsMethodInfo     = typeof(string).GetMethod("Contains", new[] { typeof(string) });
            var stringEndsWithMethodInfo     = typeof(string).GetMethod("EndsWith", new[] { typeof(string) });
            var enumerableContainsMethodInfo = typeof(Enumerable).GetMethods(BindingFlags.Public | BindingFlags.Static)
                                               .First(m => m.Name == "Contains" &&
                                                      m.GetParameters().Length == 2)
                                               .MakeGenericMethod(entityPropertyFilter.ValueType);

            var noneExpression       = Expression.Constant(true);
            var defaultExpression    = Expression.Constant(false);
            var arguments            = new Expression[] { firstValueExpression };
            var startsWithExpression = entityPropertyFilter.ValueType == typeof(string) ? Expression.Call(entityPropertyExpression, stringStartsWithMethodInfo, arguments) : null;
            var containsExpression   = entityPropertyFilter.ValueType == typeof(string) ? Expression.Call(entityPropertyExpression, stringContainsMethodInfo, arguments) : null;
            var endsWithExpression   = entityPropertyFilter.ValueType == typeof(string) ? Expression.Call(entityPropertyExpression, stringEndsWithMethodInfo, arguments) : null;
            var inExpression         = Expression.Call(enumerableContainsMethodInfo, new Expression[] { valuesExpression, entityPropertyExpression });
            var equalsExpression     = Expression.Equal(entityPropertyExpression, firstValueExpression);
            BinaryExpression greaterThanExpression = null;
            BinaryExpression lessThanExpression    = null;
            BinaryExpression betweenExpression     = null;

            if (entityPropertyFilter.ValueType != typeof(string))
            {
                greaterThanExpression = Expression.GreaterThan(entityPropertyExpression, firstValueExpression);
                lessThanExpression    = Expression.LessThan(entityPropertyExpression, firstValueExpression);
                if (secondValueExpression != null)
                {
                    betweenExpression = Expression.And(greaterThanExpression, Expression.LessThan(entityPropertyExpression, secondValueExpression));
                }
            }

            switch (entityPropertyFilter.ComparisonOperator)
            {
            case ComparisonOperator.None:
                return(Expression.Lambda <Func <TEntity, bool> >(noneExpression, entityParameter));

            case ComparisonOperator.In:
                return(Expression.Lambda <Func <TEntity, bool> >(inExpression, entityParameter));

            case ComparisonOperator.NotIn:
                return(Expression.Lambda <Func <TEntity, bool> >(Expression.Not(inExpression), entityParameter));

            case ComparisonOperator.Between:
                return(Expression.Lambda <Func <TEntity, bool> >(betweenExpression, entityParameter));

            case ComparisonOperator.StartsWith:
                return(Expression.Lambda <Func <TEntity, bool> >(startsWithExpression, entityParameter));

            case ComparisonOperator.Contains:
                return(Expression.Lambda <Func <TEntity, bool> >(containsExpression, entityParameter));

            case ComparisonOperator.EndsWith:
                return(Expression.Lambda <Func <TEntity, bool> >(endsWithExpression, entityParameter));

            case ComparisonOperator.Equals:
                return(Expression.Lambda <Func <TEntity, bool> >(equalsExpression, entityParameter));

            case ComparisonOperator.NotEquals:
                return(Expression.Lambda <Func <TEntity, bool> >(Expression.Not(equalsExpression), entityParameter));

            case ComparisonOperator.GreaterThan:
                return(Expression.Lambda <Func <TEntity, bool> >(greaterThanExpression, entityParameter));

            case ComparisonOperator.LessThan:
                return(Expression.Lambda <Func <TEntity, bool> >(lessThanExpression, entityParameter));

            default:
                return(Expression.Lambda <Func <TEntity, bool> >(defaultExpression, entityParameter));
            }
        }
コード例 #3
0
 public EntityPropertySelector(EntityPropertyFilter filter)
 {
     this.filter = filter;
 }
コード例 #4
0
            public EntityPropertySelector(EntityPropertyFilterConfig parent, string key, Func <HttpRequestMessage, bool> filterExpression)
            {
                this.filter = new EntityPropertyFilter(typeof(TEntityType), key, filterExpression);

                parent.Filters.Add(this.filter);
            }