我有一组这种形式的搜索条件: member | value | operator --------+---------+--------- height | 10 | > height | 2 | < name | Carl | ==我想查询符合任何这些条件的所有对象。现在,我正在这样做: 为每个人建立一个表达式 的标准 使用“OR”连接每个表达式表达式 构建一个 lambda表达式包含连接表达式 将 lambda 表达式传递给 IQueryable.Where() 方法 您知道使用连续 OR 来过滤 IQueryable 集合的最简单方法吗?我们的解决方案:基于 IlyaBuiluk solution @ CodeProject// The structure used by the new extension methodpublic struct SearchCriteria{ public string Column; public object Value; public WhereOperation Operation;}// How to convert the rules structure to the search criteria structurevar searchCriterias = grid.Where.rules.Select(Rule => new SearchCriteria { Column = Rule.field, Operation = (WhereOperation) StringEnum.Parse( typeof (WhereOperation), Rule.op), Value = Rule.data }).ToArray();// Usage:query = query.WhereOr(searchCriterias);// Implementationpublic static IQueryable<T> WhereOr<T>( this IQueryable<T> Query, SearchCriteria [ ] Criterias ){ if( Criterias.Count( ) == 0 ) return Query; LambdaExpression lambda; Expression resultCondition = null; // Create a member expression pointing to given column ParameterExpression parameter = Expression.Parameter( Query.ElementType, "p" ); foreach( var searchCriteria in Criterias ) { if( string.IsNullOrEmpty( searchCriteria.Column ) ) continue; MemberExpression memberAccess = null; foreach( var property in searchCriteria.Column.Split( '.' ) ) memberAccess = MemberExpression.Property ( memberAccess ?? ( parameter as Expression ), property ); // Change the type of the parameter 'value'. it is necessary for comparisons (specially for booleans) ConstantExpression filter = Expression.Constant ( Convert.ChangeType( searchCriteria.Value, memberAccess.Type ) ); //switch operation Expression condition = null; switch( searchCriteria.Operation ) { //equal == case WhereOperation.Equal: condition = Expression.Equal( memberAccess, filter ); break; //not equal != case WhereOperation.NotEqual: condition = Expression.NotEqual( memberAccess, filter ); break; // Greater case WhereOperation.Greater: condition = Expression.GreaterThan( memberAccess, filter ); break; // Greater or equal case WhereOperation.GreaterOrEqual: condition = Expression.GreaterThanOrEqual( memberAccess, filter ); break; // Less case WhereOperation.Less: condition = Expression.LessThan( memberAccess, filter ); break; // Less or equal case WhereOperation.LessEqual: condition = Expression.LessThanOrEqual( memberAccess, filter ); break; //string.Contains() case WhereOperation.Contains: condition = Expression.Call( memberAccess, typeof( string ).GetMethod( "Contains" ), Expression.Constant( searchCriteria.Value ) ); break; default: continue; } resultCondition = resultCondition != null ? Expression.Or( resultCondition, condition ): condition; } lambda = Expression.Lambda( resultCondition, parameter ); MethodCallExpression result = Expression.Call( typeof( Queryable ), "Where", new [ ] { Query.ElementType }, Query.Expression, lambda ); return Query.Provider.CreateQuery<T>( result );} 最佳答案 如果你有一组固定的运算符和一组固定的成员,那么你几乎可以不用直接处理表达式树来编写它。这个想法是为各种代码段创建简单的 lambda 表达式(例如,用于读取成员属性的 Expression<Func<Entity, string>> 和用于运算符的类似代码),然后将它们组合起来以构建表达式树。我 described the solution here 。唯一的问题是 C# 不直接支持组合表达式,因此您需要进行一些预处理(请参阅有关“可扩展实用程序”的部分)。然后,您可以将基本功能存储在字典中,并根据用户的选择选择正确的功能(或它们的组合)。例如类似的东西:NorthwindDataContext db = new NorthwindDataContext();// A query that tests whether a property// (specified by 'selector' matches a string valuevar queryBuilder = Linq.Func ((Expression<Func<Customer, string>> selector, string val) => from c in db.Customers.ToExpandable() where selector.Expand(c).IndexOf(val) != -1 select c);// Dictionary with supported members...var dict = new Dictionary<string, Expression<Func<Customer, string>>> { { "CompanyName", c => c.CompanyName }, { "Country", c => c.Country }, { "ContactName", c => c.ContactName } };// Ask user for a property name & value and Build the querystring field = Console.ReadLine();string value = Console.ReadLine();var q = queryBuilder(dict[field], value);本文还包含一个动态组合 OR 或 AND 条件的示例。我有一段时间没有更新代码,所以它需要一些工作,但我相信 LINQ KIT 项目也包含这个想法的一个版本。关于c# - IQueryable:动态创建 OR 过滤,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3712803/ 10-13 06:45