Example #1
0
        protected override Expression VisitMethodCall(MethodCallExpression methodCallExpression)
        {
            var properties = MemberAccessBindingExpressionVisitor.GetPropertyPath(methodCallExpression,
                                                                                  _queryCompilationContext, out var qsre);

            return(_selectExpression.BindPropertyPath(qsre, properties) ?? base.VisitMethodCall(methodCallExpression));
        }
        protected override Expression VisitMethodCall(MethodCallExpression methodCallExpression)
        {
            if (methodCallExpression.Method.IsEFPropertyMethod())
            {
                var source    = methodCallExpression.Arguments[0];
                var newSource = Visit(source);

                if (source != newSource)
                {
                    if (newSource.Type == typeof(JObject))
                    {
                        var properties = MemberAccessBindingExpressionVisitor.GetPropertyPath(
                            methodCallExpression, _queryModelVisitor.QueryCompilationContext, out var qsre);

                        if (qsre != null)
                        {
                            foreach (var property in properties)
                            {
                                newSource = CreateGetValueExpression(
                                    newSource, property);
                            }

                            return(newSource);
                        }
                    }
                }
            }

            return(base.VisitMethodCall(methodCallExpression));
        }
        protected override Expression VisitMember(MemberExpression memberExpression)
        {
            var newExpression = Visit(memberExpression.Expression);

            if (newExpression != memberExpression.Expression)
            {
                if (newExpression.Type == typeof(JObject))
                {
                    var properties = MemberAccessBindingExpressionVisitor.GetPropertyPath(
                        memberExpression, _queryModelVisitor.QueryCompilationContext, out var qsre);

                    if (qsre != null)
                    {
                        foreach (var property in properties)
                        {
                            newExpression = CreateGetValueExpression(
                                newExpression, property);
                        }

                        return(newExpression);
                    }
                }

                return(Expression.MakeMemberAccess(newExpression, memberExpression.Member));
            }

            return(memberExpression);
        }
        private static Expression HandleValueFromOpenJson(
            EntityQueryModelVisitor entityQueryModelVisitor,
            ValueFromOpenJsonOperator valueFromOpenJsonOperator,
            QueryModel queryModel)
        {
            var visitor = new MemberAccessBindingExpressionVisitor(entityQueryModelVisitor.QueryCompilationContext.QuerySourceMapping
                                                                   , entityQueryModelVisitor
                                                                   , false);

            if (valueFromOpenJsonOperator.Json is MemberExpression me)
            {
                if (me.Expression is ParameterExpression pe)
                {
                    var mapping = entityQueryModelVisitor.QueryCompilationContext.QuerySourceMapping;
                    if (mapping.ContainsMapping(queryModel.MainFromClause))
                    {
                        if (QuerySourceMappingLookup.GetValue(mapping) is IDictionary <IQuerySource, Expression> lookup)
                        {
                            var source = lookup.Keys.FirstOrDefault(s => s.ItemType == pe.Type && s.ItemName == pe.Name);
                            source = source ?? lookup.Keys.SingleOrDefault(s => s.ItemType == pe.Type);
                            if (source != null)
                            {
                                var exp = mapping.GetExpression(source);
                                if (exp != null)
                                {
                                    if (exp.Type == typeof(ValueBuffer))
                                    {
                                        var entityType = entityQueryModelVisitor.QueryCompilationContext.Model.FindEntityType(pe.Type);
                                        if (entityType != null)
                                        {
                                            var prop = entityType.FindProperty(me.Member as PropertyInfo);
                                            if (prop != null)
                                            {
                                                var json = entityQueryModelVisitor.BindMemberToValueBuffer(me, exp);
                                                return(Expression.Call(valueFromOpenJsonOperator.ParseInfo.ParsedExpression.Method
                                                                       , valueFromOpenJsonOperator.ParseInfo.ParsedExpression.Arguments[0]
                                                                       , json
                                                                       , valueFromOpenJsonOperator.Path));
                                            }
                                        }
                                    }

                                    var meexp = Expression.MakeMemberAccess(exp, me.Member);
                                    return(Expression.Call(valueFromOpenJsonOperator.ParseInfo.ParsedExpression.Method
                                                           , valueFromOpenJsonOperator.ParseInfo.ParsedExpression.Arguments[0]
                                                           , meexp
                                                           , valueFromOpenJsonOperator.Path));
                                }
                            }
                        }
                    }
                }
            }

            return(entityQueryModelVisitor.Expression);
        }
Example #5
0
        private bool TryPopulateIncludeLoadTree(
            IncludeResultOperator includeResultOperator,
            IncludeLoadTree includeLoadTree,
            bool shouldThrow)
        {
            if (includeResultOperator.NavigationPaths != null)
            {
                foreach (var navigationPath in includeResultOperator.NavigationPaths)
                {
                    includeLoadTree.AddLoadPath(navigationPath);
                }

                return(true);
            }

            IEntityType entityType = null;

            if (includeResultOperator.PathFromQuerySource is QuerySourceReferenceExpression qsre)
            {
                entityType = _queryCompilationContext.FindEntityType(qsre.ReferencedQuerySource);
            }

            if (entityType == null)
            {
                entityType = _queryCompilationContext.Model.FindEntityType(includeResultOperator.PathFromQuerySource.Type);

                if (entityType == null)
                {
                    var pathFromSource = MemberAccessBindingExpressionVisitor.GetPropertyPath(
                        includeResultOperator.PathFromQuerySource, _queryCompilationContext, out qsre);

                    if (pathFromSource.Count > 0 &&
                        pathFromSource[pathFromSource.Count - 1] is INavigation navigation)
                    {
                        entityType = navigation.GetTargetType();
                    }
                }
            }

            if (entityType == null)
            {
                if (shouldThrow)
                {
                    throw new InvalidOperationException(
                              CoreStrings.IncludeNotSpecifiedDirectlyOnEntityType(
                                  includeResultOperator.ToString(),
                                  includeResultOperator.NavigationPropertyPaths.FirstOrDefault()));
                }

                return(false);
            }

            return(WalkNavigations(entityType, includeResultOperator.NavigationPropertyPaths, includeLoadTree, shouldThrow));
        }
Example #6
0
        protected override Expression VisitMethodCall(MethodCallExpression methodCallExpression)
        {
            var properties = MemberAccessBindingExpressionVisitor.GetPropertyPath(methodCallExpression,
                                                                                  _queryCompilationContext, out var qsre);

            var newExpression = _selectExpression.BindPropertyPath(qsre, properties);

            if (newExpression == null)
            {
                Translated = false;
                return(methodCallExpression);
            }

            return(newExpression);
        }
        protected override Expression VisitMember(MemberExpression memberExpression)
        {
            var newExpression = Visit(memberExpression.Expression);

            if (newExpression != memberExpression.Expression)
            {
                if (_queryModelVisitor.CurrentParameter?.Type == typeof(JObject) ||
                    newExpression.Type == typeof(JObject))
                {
                    if (_queryModelVisitor.AllMembersBoundToJObject)
                    {
                        var properties = MemberAccessBindingExpressionVisitor.GetPropertyPath(
                            memberExpression, _queryModelVisitor.QueryCompilationContext, out var qsre);

                        if (qsre != null)
                        {
                            foreach (var property in properties)
                            {
                                if (property is INavigation)
                                {
                                    _queryModelVisitor.AllMembersBoundToJObject = false;

                                    return(memberExpression);
                                }

                                newExpression = CreateGetValueExpression(newExpression, (IProperty)property);
                            }

                            if (newExpression != null)
                            {
                                return(newExpression);
                            }
                        }
                    }

                    _queryModelVisitor.AllMembersBoundToJObject = false;

                    return(memberExpression);
                }

                return(Expression.MakeMemberAccess(newExpression, memberExpression.Member));
            }

            return(memberExpression);
        }
Example #8
0
        protected override Expression VisitSubQuery(SubQueryExpression expression)
        {
            // Prefer the default EF Core translation if one exists
            var result = base.VisitSubQuery(expression);

            if (result != null)
            {
                return(result);
            }

            var subQueryModel  = expression.QueryModel;
            var fromExpression = subQueryModel.MainFromClause.FromExpression;

            var properties = MemberAccessBindingExpressionVisitor.GetPropertyPath(
                fromExpression, _queryModelVisitor.QueryCompilationContext, out var qsre);

            if (properties.Count == 0)
            {
                return(null);
            }
            var lastPropertyType = properties[properties.Count - 1].ClrType;

            if (lastPropertyType.IsArray && lastPropertyType.GetArrayRank() == 1)
            {
                // Translate someArray.Length
                if (subQueryModel.ResultOperators.First() is CountResultOperator)
                {
                    return(Expression.ArrayLength(Visit(fromExpression)));
                }

                // Translate someArray.Contains(someValue)
                if (subQueryModel.ResultOperators.First() is ContainsResultOperator contains)
                {
                    var containsItem = Visit(contains.Item);
                    if (containsItem != null)
                    {
                        return(new ArrayAnyExpression(containsItem, Visit(fromExpression)));
                    }
                }
            }

            return(null);
        }
        protected override Expression VisitMethodCall(MethodCallExpression methodCallExpression)
        {
            if (_queryModelVisitor.CurrentParameter?.Type == typeof(JObject))
            {
                if (methodCallExpression.Method.IsEFPropertyMethod())
                {
                    var source    = methodCallExpression.Arguments[0];
                    var newSource = Visit(source);

                    if (source != newSource &&
                        _queryModelVisitor.AllMembersBoundToJObject &&
                        newSource.Type == typeof(JObject))
                    {
                        var properties = MemberAccessBindingExpressionVisitor.GetPropertyPath(
                            methodCallExpression, _queryModelVisitor.QueryCompilationContext, out var qsre);

                        if (qsre != null)
                        {
                            Debug.Assert(properties.Count == 1);

                            newSource = CreateGetValueExpression(newSource, (IProperty)properties[0]);

                            if (newSource != null)
                            {
                                return(newSource);
                            }
                        }
                    }
                }

                _queryModelVisitor.AllMembersBoundToJObject = false;
                return(methodCallExpression);
            }

            var newExpression = (MethodCallExpression)base.VisitMethodCall(methodCallExpression);

            return(_queryModelVisitor.BindMethodCallToEntity(methodCallExpression, newExpression) ?? newExpression);
        }
Example #10
0
        protected override Expression VisitBinary(BinaryExpression expression)
        {
            if (expression.NodeType == ExpressionType.ArrayIndex)
            {
                var properties = MemberAccessBindingExpressionVisitor.GetPropertyPath(
                    expression.Left, _queryModelVisitor.QueryCompilationContext, out var qsre);
                if (properties.Count == 0)
                {
                    return(base.VisitBinary(expression));
                }
                var lastPropertyType = properties[properties.Count - 1].ClrType;
                if (lastPropertyType.IsArray && lastPropertyType.GetArrayRank() == 1)
                {
                    var left  = Visit(expression.Left);
                    var right = Visit(expression.Right);

                    return(left != null && right != null
                        ? Expression.MakeBinary(ExpressionType.ArrayIndex, left, right)
                        : null);
                }
            }
            return(base.VisitBinary(expression));
        }