如何通过循环动态构建多Contains或条件的Lambda表达式树
Dynamic Lambda Expression Tree for Multiple OR Contains Checks
Got it, let's ditch those repetitive if-else blocks and build that OR chain dynamically. Here's how you can do it step by step:
Core Idea
We'll use Expression.OrElse to chain together multiple Contains call expressions. Start with the first Contains check, then iterate through the rest of your values, merging each new Contains into the existing expression with OR logic.
Step-by-Step Implementation
- Create the parameter expression: This represents the
xin your lambda (x => ...). - Get the property access expression: Target the
fonctionproperty on theContactstype. - Build individual Contains expressions: For each value in your list, create an expression that calls
string.Containsonx.fonctionwith the current value. - Chain expressions with OrElse: Combine all the individual
Containsexpressions into a single expression using OR logic. If there's only one value, we just use that single expression. - Assemble the final Lambda: Wrap the parameter and the combined expression into an
Expression<Func<Contacts, bool>>.
Full Code Example
List<string> values = new List<string> { "value1", "value2", "value3", "value4", "value5" }; // 1. Define the parameter for the lambda (x) ParameterExpression param = Expression.Parameter(typeof(Contacts), "x"); // 2. Get the access to x.fonction MemberExpression fonctionProp = Expression.Property(param, nameof(Contacts.fonction)); Expression? combinedExpr = null; foreach (var value in values) { // 3. Create a constant expression for the current value ConstantExpression valueConst = Expression.Constant(value, typeof(string)); // 3. Build the Contains call: x.fonction.Contains(value) MethodCallExpression containsCall = Expression.Call( fonctionProp, typeof(string).GetMethod(nameof(string.Contains), new[] { typeof(string) })!, valueConst ); // 4. Chain with OrElse if (combinedExpr == null) { combinedExpr = containsCall; } else { combinedExpr = Expression.OrElse(combinedExpr, containsCall); } } // Fallback in case values is empty (adjust this based on your needs) if (combinedExpr == null) { // Example: return false if no values, or you could return true combinedExpr = Expression.Constant(false); } // 5. Build the final lambda expression Expression<Func<Contacts, bool>> expr1 = Expression.Lambda<Func<Contacts, bool>>(combinedExpr, param);
Notes
- Make sure to handle the empty
valuescase (we added a fallback here, but you can adjust it to fit your business logic—like returningtrueif there are no filters, or throwing an exception). - The
GetMethodcall usesnameofto avoid magic strings, which makes the code more maintainable. - This approach works for any number of values, so you don't have to update code when the list grows or shrinks.
内容的提问来源于stack exchange,提问作者Bob5421
相关产品推荐
相关产品推荐

