示例#1
0
        // TODO -- pull this out somewhere else
        private IWhereFragment buildSimpleWhereClause(IQueryableDocument mapping, BinaryExpression binary)
        {
            var isValueExpressionOnRight = binary.Right.IsValueExpression();
            var jsonLocatorExpression    = isValueExpressionOnRight ? binary.Left : binary.Right;
            var valueExpression          = isValueExpressionOnRight ? binary.Right : binary.Left;

            var op = _operators[binary.NodeType];

            var isSubQuery = isValueExpressionOnRight
                ? binary.Left is SubQueryExpression
                : binary.Right is SubQueryExpression;

            if (isSubQuery)
            {
                return(buildChildCollectionQuery(mapping, jsonLocatorExpression.As <SubQueryExpression>().QueryModel, valueExpression, op));
            }

            var members = FindMembers.Determine(jsonLocatorExpression);

            var field = mapping.FieldFor(members);


            var value       = field.GetValue(valueExpression);
            var jsonLocator = field.SqlLocator;

            var useContainment = mapping.PropertySearching == PropertySearching.ContainmentOperator || field.ShouldUseContainmentOperator();

            var isDuplicated = (mapping.FieldFor(members) is DuplicatedField);

            if (useContainment &&
                binary.NodeType == ExpressionType.Equal && value != null && !isDuplicated)
            {
                return(new ContainmentWhereFragment(_serializer, binary));
            }



            if (value == null)
            {
                var sql = binary.NodeType == ExpressionType.NotEqual
                    ? $"({jsonLocator}) is not null"
                    : $"({jsonLocator}) is null";

                return(new WhereFragment(sql));
            }
            if (jsonLocatorExpression.NodeType == ExpressionType.Modulo)
            {
                var moduloByValue = MartenExpressionParser.moduloByValue(binary);
                return(new WhereFragment("{0} % {1} {2} ?".ToFormat(jsonLocator, moduloByValue, op), value));
            }


            return(new WhereFragment("{0} {1} ?".ToFormat(jsonLocator, op), value));
        }
示例#2
0
        private IWhereFragment buildChildCollectionQuery(IQueryableDocument mapping, QueryModel query, Expression valueExpression, string op)
        {
            var members = FindMembers.Determine(query.MainFromClause.FromExpression);
            var field   = mapping.FieldFor(members);

            if (query.HasOperator <CountResultOperator>())
            {
                var value = field.GetValue(valueExpression);

                return(new WhereFragment($"jsonb_array_length({field.SqlLocator}) {op} ?", value));
            }

            throw new NotSupportedException("Marten does not yet support this type of Linq query against child collections");
        }
        public void Parse()
        {
            var invalidOperators = _query.ResultOperators.Where(x => !ValidOperators.Contains(x.GetType()))
                                   .ToArray();

            if (invalidOperators.Any())
            {
                var names = invalidOperators.Select(x => x.GetType().Name).Join(", ");
                throw new NotSupportedException($"Marten does not yet support {names} operators in child collection queries");
            }

            var members     = FindMembers.Determine(_query.MainFromClause.FromExpression);
            var queryType   = _query.SourceType();
            var isPrimitive = TypeMappings.HasTypeMapping(queryType);



            Visit(_expression);

            // Simple types

            if (isPrimitive)
            {
                var contains = _query.ResultOperators.OfType <ContainsResultOperator>().FirstOrDefault();
                if (contains != null)
                {
                    var @where = ContainmentWhereFragment.SimpleArrayContains(members, _serializer, _query.MainFromClause.FromExpression, contains.Item.Value());
                    _registerFilter(@where);

                    return;
                }
            }

            if (_query.ResultOperators.Any(x => x is AnyResultOperator))
            {
                // Any() without predicate
                if (!_query.BodyClauses.Any())
                {
                    var @where_any_nopredicate = new CollectionAnyNoPredicateWhereFragment(members, _expression);

                    _registerFilter(@where_any_nopredicate);

                    return;
                }

                var @where = new CollectionAnyContainmentWhereFragment(members, _serializer, _expression);
                _registerFilter(@where);
            }
        }