using System; using System.Linq; using System.Linq.Expressions; namespace Utils { public static class Resolver { /// /// 将字符串表达式解析为一个谓词函数,该函数可以用于筛选实体对象。 /// /// 表示条件的字符串表达式。格式示例:"entity.Id > 10" 或 "entity.Name == 'John'"。 /// 返回一个 Func<Entity.Entity, bool> 类型的委托,表示解析后的谓词函数。 /// 当输入表达式的格式不正确时抛出此异常。 /// 当表达式中包含不支持的操作符或数据类型时抛出此异常。 /// /// 表达式的格式必须符合以下规则: /// - 表达式由三部分组成:属性路径、操作符和值,用空格分隔。 /// - 属性路径格式为 "entity.PropertyName",其中 PropertyName 是实体类中的一个公共属性或字段。 /// - 操作符可以是以下之一:">", "<", ">=", "<=", "==", "!="。 /// - 值的类型必须与属性的类型匹配,并且支持以下类型:string, int, long, float, double, decimal, bool, DateTime, Guid 和枚举类型。 /// /// 注意事项: /// - 字符串值需要用单引号或双引号括起来,例如 'John' 或 "John"。 /// - 对于可为空类型(Nullable),会自动处理其底层类型的转换。 /// - 字符串比较默认使用不区分大小写的 Equals 方法。 /// public static Func ParsePredicate(string expression) { // 格式示例:"entity.Id > 10" 或 "entity.Name == 'John'" var parts = expression.Split(new[] { ' ' }, 3, StringSplitOptions.RemoveEmptyEntries); if (parts.Length != 3) throw new FormatException( "Invalid expression format. Expected format: 'entity.Property Operator Value'"); // 解析属性和操作符 var propPath = parts[0].Split('.')[1]; // "Id" 或 "Name" var op = parts[1]; // ">", "==" 等 // 创建表达式参数 var param = Expression.Parameter(typeof(Entity.Entity), "entity"); // 获取属性访问表达式 var propAccess = propPath.Split('.') .Aggregate(param, Expression.PropertyOrField); // 获取属性类型 var propType = propAccess.Type; // 解析值并转换为适当类型 object value; var valueStr = parts[2].Trim(); try { if (propType == typeof(string)) // 处理字符串值(去除引号) value = valueStr.Trim('\'', '"'); else if (propType == typeof(int)) value = int.Parse(valueStr); else if (propType == typeof(long)) value = long.Parse(valueStr); else if (propType == typeof(float)) value = float.Parse(valueStr); else if (propType == typeof(double)) value = double.Parse(valueStr); else if (propType == typeof(decimal)) value = decimal.Parse(valueStr); else if (propType == typeof(bool)) value = bool.Parse(valueStr); else if (propType == typeof(DateTime)) value = DateTime.Parse(valueStr); else if (propType == typeof(Guid)) value = Guid.Parse(valueStr); else if (propType.IsEnum) value = Enum.Parse(propType, valueStr); else throw new NotSupportedException($"Type {propType.Name} is not supported"); } catch (Exception ex) { throw new FormatException($"Failed to parse value '{valueStr}' for type {propType.Name}", ex); } // 创建常量表达式(确保类型匹配) var constant = Expression.Constant(value, propType); // 处理可为空类型的情况 if (propType.IsGenericType && propType.GetGenericTypeDefinition() == typeof(Nullable<>)) { var underlyingType = Nullable.GetUnderlyingType(propType); propAccess = Expression.Property(propAccess, "Value"); constant = Expression.Constant(Convert.ChangeType(value, underlyingType), underlyingType); } // 创建比较表达式 Expression comparison; if (propType == typeof(string) && (op == "==" || op == "!=")) { // 字符串特殊处理:使用Equals方法进行不区分大小写的比较 var equalsMethod = typeof(string).GetMethod("Equals", new[] { typeof(string), typeof(StringComparison) }); var methodCall = Expression.Call( propAccess, equalsMethod, constant, Expression.Constant(StringComparison.OrdinalIgnoreCase)); comparison = op == "==" ? methodCall : Expression.Not(methodCall); } else { // 其他类型使用标准二元运算符 comparison = op switch { ">" => Expression.GreaterThan(propAccess, constant), "<" => Expression.LessThan(propAccess, constant), ">=" => Expression.GreaterThanOrEqual(propAccess, constant), "<=" => Expression.LessThanOrEqual(propAccess, constant), "==" => Expression.Equal(propAccess, constant), "!=" => Expression.NotEqual(propAccess, constant), _ => throw new NotSupportedException($"Operator {op} not supported") }; } // 编译为委托 var lambda = Expression.Lambda>(comparison, param); return lambda.Compile(); } } }