1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | static IEnumerable<MethodInfo> GetExtensionMethods(Assembly assembly, Type extendedType) { var query = from type in assembly.GetTypes() where !type.IsGenericType && !type.IsNested from method in type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) where method.IsDefined( typeof (System.Runtime.CompilerServices.ExtensionAttribute), false ) where method.GetParameters()[0].ParameterType == extendedType select method; return query; } public static Expression<Func<T, bool >> IsGreaterThan<T>( string propertyName, byte [] values) where T : class { if (values == null || !values.Any()) { throw new ArgumentException( "The values collection must not be null or empty." , nameof(values)); } // 获取泛型类型 T 的 PropertyInfo var propertyInfo = typeof (T).GetProperty(propertyName); if (propertyInfo == null ) { throw new ArgumentException($ "Property '{propertyName}' not found on type '{typeof(T).Name}'." , nameof(propertyName)); } // 创建参数表达式,表示 T 类型的实例 var parameter = Expression.Parameter( typeof (T), "entity" ); // 创建属性访问表达式,表示访问 T 类型的 propertyName 属性 var propertyAccess = Expression.Property(parameter, propertyInfo); // 将 values 集合转换为 Expression 常量数组 var constantExpression = Expression.NewArrayInit( typeof ( byte ), values.Select(v => (Expression)Expression.Constant(v, typeof ( byte )))); // 创建 Contains 方法调用表达式,注意这里我们假设 TValue 是可比较的,并且支持 Contains 方法 // 实际上,在 LINQ to Entities 中,我们需要使用 DbSet.Contains 或者手动映射到 SQL 的 IN 子句 // 这里我们使用一个假设的 Contains 方法作为演示,实际中需要替换为合适的实现 \\ Assembly assembly = Assembly.GetExecutingAssembly(); var dd = typeof ( byte []).GetMethods().ToList(); var containsMethod = GetExtensionMethods(assembly, typeof ( byte [])) .Single(m => m.Name == "Compare" && m.GetParameters().Length == 2) ; var containsExpression = Expression.Call( null , // 对于静态方法,第一个参数是 null containsMethod, constantExpression, // 数组参数 propertyAccess // 要检查是否包含的属性值 ); // 注意:上面的 ContainsExpression 在 EF Core 中不会直接工作,因为它引用的是 Enumerable.Contains // 而不是 EF Core 能够转换为 SQL IN 子句的表达式。因此,在实际应用中,你可能需要手动构建 Expression.Call // 调用数据库上下文中的某个 DbSet 的 Contains 方法,或者使用其他方法将表达式转换为 SQL IN 子句。 // 创建一个 lambda 表达式 var lambda = Expression.Lambda<Func<T, int >>(containsExpression, parameter); var parameter2 = lambda.Parameters[0]; // 获取原始lambda的参数 var body = Expression.LessThan(lambda.Body, Expression.Constant(0)); // 创建新的body,检查是否大于10 Expression<Func<T, bool >> newLambda = Expression.Lambda<Func<T, bool >>(body, parameter2); // 返回 lambda 表达式,但请注意,它可能不会在 EF Core 中直接工作,除非你进一步处理它 return newLambda; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | public static Expression<Func<T, bool >> BuildInExpression<T, TValue>( string propertyName, IEnumerable<TValue> values) { if (values == null || !values.Any()) { throw new ArgumentException( "The values collection must not be null or empty." , nameof(values)); } // 获取泛型类型 T 的 PropertyInfo var propertyInfo = typeof (T).GetProperty(propertyName); if (propertyInfo == null ) { throw new ArgumentException($ "Property '{propertyName}' not found on type '{typeof(T).Name}'." , nameof(propertyName)); } // 创建参数表达式,表示 T 类型的实例 var parameter = Expression.Parameter( typeof (T), "entity" ); // 创建属性访问表达式,表示访问 T 类型的 propertyName 属性 var propertyAccess = Expression.Property(parameter, propertyInfo); // 将 values 集合转换为 Expression 常量数组 var constantExpression = Expression.NewArrayInit( typeof (TValue), values.Select(v => (Expression)Expression.Constant(v, typeof (TValue)))); // 创建 Contains 方法调用表达式,注意这里我们假设 TValue 是可比较的,并且支持 Contains 方法 // 实际上,在 LINQ to Entities 中,我们需要使用 DbSet.Contains 或者手动映射到 SQL 的 IN 子句 // 这里我们使用一个假设的 Contains 方法作为演示,实际中需要替换为合适的实现 var containsMethod = typeof (Enumerable).GetMethods() .Single(m => m.Name == "Contains" && m.GetParameters().Length == 2) .MakeGenericMethod( typeof (TValue)); var containsExpression = Expression.Call( null , // 对于静态方法,第一个参数是 null containsMethod, constantExpression, // 数组参数 propertyAccess // 要检查是否包含的属性值 ); // 注意:上面的 ContainsExpression 在 EF Core 中不会直接工作,因为它引用的是 Enumerable.Contains // 而不是 EF Core 能够转换为 SQL IN 子句的表达式。因此,在实际应用中,你可能需要手动构建 Expression.Call // 调用数据库上下文中的某个 DbSet 的 Contains 方法,或者使用其他方法将表达式转换为 SQL IN 子句。 // 创建一个 lambda 表达式 var lambda = Expression.Lambda<Func<T, bool >>(containsExpression, parameter); // 返回 lambda 表达式,但请注意,它可能不会在 EF Core 中直接工作,除非你进一步处理它 return lambda; } |