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); } }