public LambdaExpression GetExpression(Dictionary <string, object> enviromens = null)
        {
            FilterValues = FilterValue?.Split(',');
            if (enviromens != null && enviromens.ContainsKey(FilterValue))
            {
                var realValue     = enviromens[FilterValue];
                var realValueType = realValue.GetType();
                if (realValueType.GetInterface(nameof(IEnumerable)) != null && typeof(string) != realValueType)
                {
                    realValueType = realValueType.GetGenericArguments()[0];
                    MethodInfo toArrayMethod = typeof(Enumerable).GetMethod("ToArray")
                                               .MakeGenericMethod(new System.Type[] { realValueType });
                    FilterValues = toArrayMethod.Invoke(null, new object[] { realValue }) as object[];
                }

                else
                {
                    FilterValues = new object[] { realValue }
                };

                if (Type.GetType(this.PropertyType) != realValueType)
                {
                    throw new NotSupportedException("the propertyType can not compare to the value type ");
                }
            }

            PropertyPath = string.Join(".", PropertyNames);
            var enityType = Type.GetType(EntityType);
            LambdaExpression lambdaExpression = null;
            var parameter = Expression.Parameter(enityType, QueryCollection.ParameterSymbol);

            switch (FieldKind)
            {
            case FieldKind.ValueType:     //如:m.Id==2 或者m.Name.Contains("a") 或者m.Group.Name="a"
            case FieldKind.Reference:     //reference下的属性处理与ValueType是一致的,其实可以忽略掉
            {
                var queryCollection = new QueryCollection();
                var query           = new Query {
                    Name = this.PropertyPath, Operator = this.Operator
                };
                switch (query.Operator)
                {
                case Operators.Range:
                {
                    query.ValueMin = this.FilterValues[0];
                    query.ValueMax = this.FilterValues[1];
                    break;
                }

                case Operators.In:
                {
                    query.Value = this.FilterValues;
                    break;
                }

                default:
                    query.Value = this.FilterValues[0];
                    break;
                }
                queryCollection.Add(query);
                var method = typeof(QueryCollection).GetMethod("AsExpression");
                method = method.MakeGenericMethod(enityType);

                lambdaExpression = (LambdaExpression)method.GetReflector().Invoke(queryCollection, Query.Condition.AndAlso);
                break;
            }

            case FieldKind.ICollection:
            {
                if (this.RuleGroup == null)
                {
                    break;
                }
                var childLambda = this.RuleGroup.GetExpression();

                var member = QueryCollection.GetPropertyExpression(parameter, PropertyPath);
                if (member.Type.GetInterface(nameof(IEnumerable)) != null)
                {
                    lambdaExpression = Expression.Lambda(
                        Expression.Call(typeof(Enumerable), "Any", new Type[] { Type.GetType(this.RuleGroup.EntityType) }, member, childLambda),
                        parameter);
                }
                break;
            }

            case FieldKind.EnvType:    //用户的上下文环境变量,在json字符串阶段需提前用变量值替换掉,替换后,propertyPath其实就是一个值
            {
                var propertyType = Type.GetType(this.PropertyType);
                if (enviromens == null)
                {
                    throw new ArgumentNullException("enviroment values is null");
                }
                if (!enviromens.ContainsKey(this.PropertyPath))
                {
                    throw new ArgumentNullException("not such enviroment key and value");
                }
                var environmentValue = enviromens[this.PropertyPath];
                var left             = Expression.Constant(environmentValue);

                Expression expression = null;
                switch (Operator)
                {
                case Query.Operators.Equal:
                {
                    var right = Expression.Constant(ReflectorHelper.ValueConvert(propertyType, FilterValues[0]));
                    expression = Expression.Equal(left, right);
                    break;
                }

                case Query.Operators.GreaterThan:
                {
                    var right = Expression.Constant(ReflectorHelper.ValueConvert(propertyType, FilterValues[0]));
                    expression = Expression.GreaterThan(left, right);

                    break;
                }

                case Query.Operators.GreaterThanOrEqual:
                {
                    var right = Expression.Constant(ReflectorHelper.ValueConvert(propertyType, FilterValues[0]));
                    expression = Expression.GreaterThanOrEqual(left, right);

                    break;
                }

                case Query.Operators.LessThan:
                {
                    var right = Expression.Constant(ReflectorHelper.ValueConvert(propertyType, FilterValues[0]));
                    expression = Expression.LessThan(left, right);

                    break;
                }

                case Query.Operators.LessThanOrEqual:
                {
                    var right = Expression.Constant(ReflectorHelper.ValueConvert(propertyType, FilterValues[0]));
                    expression = Expression.LessThanOrEqual(left, right);

                    break;
                }

                case Query.Operators.Contains:
                {
                    var itemType = propertyType != typeof(string) && propertyType.GetInterface(nameof(IEnumerable)) != null ? propertyType.GenericTypeArguments[0] : propertyType;
                    var right    = Expression.Constant(ReflectorHelper.ValueConvert(itemType, FilterValues[0]));
                    expression = Expression.Call(left, "Contains", null, right);
                    break;
                }

                case Query.Operators.In:            //value必须是集合类型
                {
                    var constantVaule = ReflectorHelper.ValueConvert(propertyType, FilterValues);
                    var right         = Expression.Constant(constantVaule);

                    expression = Expression.Call(typeof(Enumerable), "Contains", new Type[] { propertyType }, right, left);

                    break;
                }

                case Query.Operators.StartWith:
                {
                    var right = Expression.Constant(ReflectorHelper.ValueConvert(propertyType, FilterValues[0]));

                    expression = Expression.Call(left, "StartsWith", null, right);

                    break;
                }

                case Query.Operators.EndWidth:
                {
                    var right = Expression.Constant(ReflectorHelper.ValueConvert(propertyType, FilterValues[0]));

                    expression = Expression.Call(left, "EndsWith", null, right);
                    break;
                }

                case Query.Operators.Range:
                {
                    Expression minExp = null, maxExp = null;
                    if (FilterValues.Length > 0 && FilterValues[0] != null)
                    {
                        var right = Expression.Constant(ReflectorHelper.ValueConvert(propertyType, FilterValues[0]));
                        minExp = Expression.GreaterThanOrEqual(left, right);
                    }
                    if (FilterValues.Length > 1 && FilterValues[1] != null)
                    {
                        var right = Expression.Constant(ReflectorHelper.ValueConvert(propertyType, FilterValues[1]));
                        maxExp = Expression.LessThanOrEqual(left, right);
                    }

                    if (minExp != null && maxExp != null)
                    {
                        expression = Expression.AndAlso(minExp, maxExp);
                    }
                    else if (minExp != null)
                    {
                        expression = minExp;
                    }
                    else if (maxExp != null)
                    {
                        expression = maxExp;
                    }

                    break;
                }
                }
                lambdaExpression = Expression.Lambda(expression, parameter);
                break;
            }

            default:
                break;
            }


            return(lambdaExpression);
        }
    }