在C#中,动态查询通常涉及到构建可组合的表达式树(Expression),这些表达式树可以代表任意复杂的查询逻辑。使用Expression类,我们可以动态地构建LINQ查询中的Where子句,从而根据运行时条件组合多个查询条件。
以下是一个简单的示例,展示了如何使用Expression类动态地构建多条件查询表达式:
首先,假设我们有一个Person类,它包含姓名、年龄和性别等属性:
csharppublic class Person
{
public string Name { get; set; }
public int Age { get; set; }
public string Gender { get; set; }
}
现在,我们想要根据用户提供的一些条件来查询Person对象的集合。这些条件可能是动态的,可能在运行时才确定。为了构建这样的查询,我们可以创建一个帮助类来组合Expression:
csharpusing System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
public static class QueryHelper<T>
{
public static Expression<Func<T, bool>> CombineExpressions(params Expression<Func<T, bool>>[] predicates)
{
if (predicates == null || predicates.Length == 0)
throw new ArgumentException("No predicates provided", nameof(predicates));
// 如果只有一个条件,直接返回它
if (predicates.Length == 1)
return predicates[0];
// 创建一个参数表达式,它将用于构建最终的Lambda表达式
var parameter = Expression.Parameter(typeof(T), "entity");
// 将每个谓词转换为可以组合的形式(使用相同的参数)
var invocations = predicates
.Select(predicate => Expression.Invoke(predicate, parameter));
// 使用AndAlso组合所有条件
var body = invocations.Aggregate((left, right) => Expression.AndAlso(left, right));
// 创建最终的Lambda表达式
return Expression.Lambda<Func<T, bool>>(body, parameter);
}
}
现在,我们可以使用QueryHelper类来构建多条件查询:
csharpList<Person> people = new List<Person>
{
new Person { Name = "Alice", Age = 25, Gender = "Female" },
new Person { Name = "Bob", Age = 30, Gender = "Male" },
new Person { Name = "Charlie", Age = 35, Gender = "Male" },
new Person { Name = "David", Age = 20, Gender = "Male" }
};
// 构建条件表达式
Expression<Func<Person, bool>> agePredicate = p => p.Age > 25;
Expression<Func<Person, bool>> genderPredicate = p => p.Gender == "Male";
// 组合条件表达式
Expression<Func<Person, bool>> combinedPredicate = QueryHelper<Person>.CombineExpressions(agePredicate, genderPredicate);
// 使用组合后的条件表达式进行查询
var filteredPeople = people.AsQueryable().Where(combinedPredicate).ToList();
foreach (var person in filteredPeople)
{
Console.WriteLine($"{person.Name} is {person.Age} years old and {person.Gender}.");
}
在这个例子中,我们创建了两个条件表达式agePredicate和genderPredicate,然后使用
QueryHelper.CombineExpressions方法将它们组合成一个新的表达式combinedPredicate。最后,我们使用这个组合后的表达式来查询people集合,并打印出满足条件的人员信息。
请注意,上述示例中使用了AndAlso来组合条件,这表示所有条件都必须满足。如果你想要使用OrElse来组合条件(即满足任何一个条件即可),只需将AndAlso替换为OrElse即可。此外,你还可以根据需要添加更多的逻辑运算符和条件。