在现代C#开发中,动态LINQ查询是一个非常实用但又略显高级的功能。它允许我们在运行时根据用户输入、配置或其他条件动态构建查询逻辑,而不是在编译时就写死。而实现这一功能的核心技术之一,就是表达式树(Expression Tree)。
本教程将带你从零开始,一步步理解并使用C#表达式树来动态创建LINQ查询。即使你是编程新手,也能轻松跟上!

在C#中,表达式树是一种数据结构,它以树形方式表示代码逻辑。与普通委托(如 Func<T, bool>)直接编译为可执行代码不同,表达式树保留了代码的结构信息,使得我们可以在运行时分析、修改甚至重新组合这些逻辑。
例如,下面这行代码:
Expression<Func<Person, bool>> expr = p => p.Age > 18;它不会立即执行,而是生成一个描述“p.Age > 18”这个条件的树结构。我们可以遍历这个树,也可以把它转换成SQL语句(如Entity Framework所做的那样)。
想象一个用户界面,用户可以选择多个筛选条件:年龄大于某个值、姓名包含某个字符串、城市等于某个选项等。如果用传统方式,你可能要写大量 if-else 来拼接查询:
var query = dbContext.People.AsQueryable();if (!string.IsNullOrEmpty(name)) query = query.Where(p => p.Name.Contains(name));if (minAge.HasValue) query = query.Where(p => p.Age >= minAge.Value);// ...更多条件这种方式虽然可行,但当条件复杂或需要组合逻辑(如“AND”、“OR”)时,代码会变得难以维护。而使用表达式树,我们可以动态构建整个Where条件,一次性传入LINQ,更高效也更灵活。
下面我们通过一个完整示例,展示如何使用表达式树动态创建LINQ查询。
首先定义一个简单的数据模型:
public class Person{ public string Name { get; set; } public int Age { get; set; } public string City { get; set; }}接下来,我们编写一个方法,接收字段名、操作符和值,返回一个表达式:
using System;using System.Linq.Expressions;public static Expression<Func<Person, bool>> BuildFilter(string propertyName, string operation, object value){ // 创建参数表达式:p var parameter = Expression.Parameter(typeof(Person), "p"); // 获取属性:p.PropertyName var property = Expression.Property(parameter, propertyName); // 将值转换为目标属性类型 var constant = Expression.Constant(Convert.ChangeType(value, property.Type)); // 根据操作符构建二元表达式 Expression body = operation.ToLower() switch { "eq" or "==" => Expression.Equal(property, constant), "gt" or ">" => Expression.GreaterThan(property, constant), "lt" or "<" => Expression.LessThan(property, constant), "contains" => Expression.Call(property, typeof(string).GetMethod("Contains", new[] { typeof(string) })!, constant), _ => throw new ArgumentException("不支持的操作符") }; // 构建Lambda表达式:p => p.Property op value return Expression.Lambda<Func<Person, bool>>(body, parameter);}现在,我们可以这样使用它:
var people = new List<Person>{ new Person { Name = "张三", Age = 25, City = "北京" }, new Person { Name = "李四", Age = 30, City = "上海" }, new Person { Name = "王五", Age = 22, City = "广州" }};// 动态构建条件:年龄大于24var filter = BuildFilter("Age", ">", 24);var result = people.AsQueryable().Where(filter).ToList();// result 将包含张三和李四实际应用中,往往需要组合多个条件(如 AND 或 OR)。我们可以使用 Expression.AndAlso 或 Expression.OrElse 来合并表达式。
public static Expression<Func<T, bool>> And<T>( Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2){ var parameter = Expression.Parameter(typeof(T)); var body = Expression.AndAlso( Expression.Invoke(expr1, parameter), Expression.Invoke(expr2, parameter) ); return Expression.Lambda<Func<T, bool>>(body, parameter);}然后你可以这样组合:
var ageFilter = BuildFilter("Age", ">", 20);var cityFilter = BuildFilter("City", "eq", "北京");var combined = And(ageFilter, cityFilter);var result = people.AsQueryable().Where(combined).ToList();通过本教程,你已经掌握了如何使用C#表达式树来动态创建LINQ查询。这项技能在构建灵活的数据筛选系统、报表引擎或通用API时非常有用。
记住,核心思路是:将代码逻辑表示为可操作的树结构,然后在运行时按需组合。虽然初看有些复杂,但一旦理解其原理,你会发现它比硬编码的条件判断更强大、更优雅。
希望这篇表达式树教程对你有所帮助!如果你正在开发需要动态LINQ构建的功能,不妨尝试一下这种方法。
关键词回顾:C#表达式树、LINQ动态查询、动态LINQ构建、表达式树教程
本文由主机测评网于2025-12-29发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://vpshk.cn/20251213733.html