我正在使用自己的IQueryable 扩展方法来创建可链接查询,例如FindAll()。FindInZip(12345).NameStartsWith(“XYZ”)。OrderByHowIWantIt()等,然后在延迟执行时基于我创建一个查询扩展方法链。但是,问题在于,扩展链中的所有位置(FindXYZ,FindInZip等)都将始终合并为AND,这意味着我无法执行以下操作:FindAll()。FirstNameStartsWith(“X”)。OrLastNameStartsWith(“Z”),因为我不知道如何将OR注入(inject)到单独的Where方法中。知道我该如何解决吗?额外的;到目前为止,我了解如何将表达式链接为或是否包装它们(例如CompileAsOr(FirstNameStartsWith(“A”)。LastNameStartsWith(“Z”)。OrderBy(..))我想做的是稍微复杂一些(PredicateBuilder在这里无济于事),因为我希望以后的IQueryable基本上访问之前建立的Where条件,而不必包装它们以创建Or之间的条件。他们。当每个扩展方法返回IQueryable 时,我了解它应该对某个地方的查询条件的当前状态有所了解,这使我相信应该有某种自动化的方法或在所有先前的Where条件中创建一个Or,而不必进行包装您想要的是什么。 最佳答案 我假设查询的不同部分仅在运行时才知道,即您不能只在||中使用where ...一个懒惰的选项是Concat-但这往往会导致不良的TSQL等。但是,我倾向于倾向于改写自定义Expression。采取的方法取决于提供者是什么,因为LINQ-to-SQL支持EF的不同选项(例如)-在这里具有真正的影响(因为您不能将子表达式与EF一起使用)。你能告诉我们哪一个吗?这是一些应在LINQ-to-SQL中使用的代码;如果您构建一个表达式数组(或列表,并调用.ToArray()),它应该可以正常工作;示例是LINQ-to-Objects,但仍然可以使用: static void Main() { var data = (new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }).AsQueryable(); var predicates = new List<Expression<Func<int, bool>>>(); predicates.Add(i => i % 3 == 0); predicates.Add(i => i >= 8); foreach (var item in data.WhereAny(predicates.ToArray())) { Console.WriteLine(item); } } public static IQueryable<T> WhereAny<T>( this IQueryable<T> source, params Expression<Func<T,bool>>[] predicates) { if (source == null) throw new ArgumentNullException("source"); if (predicates == null) throw new ArgumentNullException("predicates"); if (predicates.Length == 0) return source.Where(x => false); // no matches! if (predicates.Length == 1) return source.Where(predicates[0]); // simple var param = Expression.Parameter(typeof(T), "x"); Expression body = Expression.Invoke(predicates[0], param); for (int i = 1; i < predicates.Length; i++) { body = Expression.OrElse(body, Expression.Invoke(predicates[i], param)); } var lambda = Expression.Lambda<Func<T, bool>>(body, param); return source.Where(lambda); }关于c# - 将IQueryable <T> Where()扩展为OR或AND关系,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/930677/
10-13 03:21