Beispiel #1
0
        /// <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.");
        }