/// <summary> /// Filters a query based upon the predicate provided. /// </summary> /// <typeparam name="TSource">The type of ParseObject being queried for.</typeparam> /// <param name="source">The base <see cref="ParseQuery{TSource}"/> to which /// the predicate will be added.</param> /// <param name="predicate">A function to test each ParseObject for a condition. /// The predicate must be able to be represented by one of the standard Where /// functions on ParseQuery</param> /// <returns>A new ParseQuery whose results will match the given predicate as /// well as the source's filters.</returns> public static ParseQuery <TSource> Where <TSource>( this ParseQuery <TSource> source, Expression <Func <TSource, bool> > predicate) where TSource : ParseObject { // Handle top-level logic operators && and || var binaryExpression = predicate.Body as BinaryExpression; if (binaryExpression != null) { if (binaryExpression.NodeType == ExpressionType.AndAlso) { return(source .Where(Expression.Lambda <Func <TSource, bool> >( binaryExpression.Left, predicate.Parameters)) .Where(Expression.Lambda <Func <TSource, bool> >( binaryExpression.Right, predicate.Parameters))); } if (binaryExpression.NodeType == ExpressionType.OrElse) { var left = source.Where(Expression.Lambda <Func <TSource, bool> >( binaryExpression.Left, predicate.Parameters)); var right = source.Where(Expression.Lambda <Func <TSource, bool> >( binaryExpression.Right, predicate.Parameters)); return(left.Or(right)); } } var normalized = new WhereNormalizer().Visit(predicate.Body); var methodCallExpr = normalized as MethodCallExpression; if (methodCallExpr != null) { return(source.WhereMethodCall(predicate, methodCallExpr)); } var binaryExpr = normalized as BinaryExpression; if (binaryExpr != null) { return(source.WhereBinaryExpression(predicate, binaryExpr)); } var unaryExpr = normalized as UnaryExpression; if (unaryExpr != null && unaryExpr.NodeType == ExpressionType.Not) { var node = unaryExpr.Operand as MethodCallExpression; if (IsParseObjectGet(node) && (node.Type == typeof(bool) || node.Type == typeof(bool?))) { // This is a raw boolean field access like 'where !obj.Get<bool>("foo")' return(source.WhereNotEqualTo(GetValue(node.Arguments[0]) as string, true)); } } throw new InvalidOperationException( "Encountered an unsupported expression for ParseQueries."); }