internal override Expression VisitMethodCall(MethodCallExpression m)
        {
            Expression expressionBeforeNormalization = this.GetExpressionBeforeNormalization(m);

            if (expressionBeforeNormalization != m)
            {
                return(this.Visit(expressionBeforeNormalization));
            }
            if (this.pathBuilder.CurrentIsEntity)
            {
                if (m.Method.Name == "Select")
                {
                    return(this.RebindMethodCallForMemberSelect(m));
                }
                if (m.Method.Name == "ToList")
                {
                    return(this.RebindMethodCallForMemberToList(m));
                }
                return(base.VisitMethodCall(m));
            }
            if (ProjectionAnalyzer.IsMethodCallAllowedEntitySequence(m))
            {
                return(this.RebindMethodCallForNewSequence(m));
            }
            return(base.VisitMethodCall(m));
        }
Esempio n. 2
0
        private Expression RebindMethodCallForNewSequence(MethodCallExpression call)
        {
            Debug.Assert(call != null, "call != null");
            Debug.Assert(ProjectionAnalyzer.IsMethodCallAllowedEntitySequence(call), "ProjectionAnalyzer.IsMethodCallAllowedEntitySequence(call)");
            Debug.Assert(call.Object == null, "call.Object == null -- otherwise this isn't the supported Select or ToList methods");

            Expression result = null;

            if (call.Method.Name == "Select")
            {
                Debug.Assert(call.Arguments.Count == 2, "call.Arguments.Count == 2 -- otherwise this isn't the argument we expected");

                Expression           parameterSource = this.Visit(call.Arguments[0]);
                ExpressionAnnotation annotation;
                this.annotations.TryGetValue(parameterSource, out annotation);

                if (annotation != null)
                {
                    Expression selectorExpression = this.Visit(call.Arguments[1]);
                    Type       returnElementType  = call.Method.ReturnType.GetGenericArguments()[0];
                    result = CallMaterializer(
                        "ProjectionSelect",
                        this.materializerExpression,
                        this.pathBuilder.ParameterEntryInScope,
                        this.pathBuilder.ExpectedParamTypeInScope,
                        Expression.Constant(returnElementType, typeof(Type)),
                        Expression.Constant(annotation.Segment.StartPath, typeof(object)),
                        selectorExpression);
                    this.annotations.Add(result, annotation);
                    result = CallMaterializerWithType(
                        "EnumerateAsElementType",
                        new Type[] { returnElementType },
                        result);
                    this.annotations.Add(result, annotation);
                }
            }
            else
            {
                Debug.Assert(call.Method.Name == "ToList", "call.Method.Name == 'ToList'");

                Expression           source = this.Visit(call.Arguments[0]);
                ExpressionAnnotation annotation;
                if (this.annotations.TryGetValue(source, out annotation))
                {
                    result = this.TypedEnumerableToList(source, call.Type);
                    this.annotations.Add(result, annotation);
                }
            }

            if (result == null)
            {
                result = base.VisitMethodCall(call);
            }

            return(result);
        }
Esempio n. 3
0
 internal override Expression VisitMethodCall(MethodCallExpression m)
 {
     if (((m.Object != null) && ProjectionAnalyzer.IsDisallowedExpressionForMethodCall(m.Object, this.context.MaxProtocolVersion)) || m.Arguments.Any <Expression>(a => ProjectionAnalyzer.IsDisallowedExpressionForMethodCall(a, this.context.MaxProtocolVersion)))
     {
         throw new NotSupportedException(System.Data.Services.Client.Strings.ALinq_ExpressionNotSupportedInProjection(this.type, m.ToString()));
     }
     ProjectionAnalyzer.CheckChainedSequence(m, this.type);
     if (!ProjectionAnalyzer.IsMethodCallAllowedEntitySequence(m) && (((m.Object != null) ? ClientTypeUtil.TypeOrElementTypeIsEntity(m.Object.Type) : false) || m.Arguments.Any <Expression>(a => ClientTypeUtil.TypeOrElementTypeIsEntity(a.Type))))
     {
         throw new NotSupportedException(System.Data.Services.Client.Strings.ALinq_ExpressionNotSupportedInProjection(this.type, m.ToString()));
     }
     return(base.VisitMethodCall(m));
 }
Esempio n. 4
0
            internal override Expression VisitMethodCall(MethodCallExpression m)
            {
                if ((m.Object != null && IsDisallowedExpressionForMethodCall(m.Object)) ||
                    m.Arguments.Any(a => IsDisallowedExpressionForMethodCall(a)))
                {
                    throw new NotSupportedException(Strings.ALinq_ExpressionNotSupportedInProjection(this.type, m.ToString()));
                }

                if (ProjectionAnalyzer.IsMethodCallAllowedEntitySequence(m))
                {
                    CheckChainedSequence(m, this.type);

                    return(base.VisitMethodCall(m));
                }

                throw new NotSupportedException(Strings.ALinq_ExpressionNotSupportedInProjectionToEntity(this.type, m.ToString()));
            }
Esempio n. 5
0
        internal override Expression VisitMethodCall(MethodCallExpression m)
        {
            Debug.Assert(m != null, "m != null");

            Expression original = this.GetExpressionBeforeNormalization(m);

            if (original != m)
            {
                return(this.Visit(original));
            }

            Expression result;

            if (this.pathBuilder.CurrentIsEntity)
            {
                Debug.Assert(
                    ProjectionAnalyzer.IsMethodCallAllowedEntitySequence(m) || ResourceBinder.PatternRules.MatchReferenceEquals(m),
                    "ProjectionAnalyzer.IsMethodCallAllowedEntitySequence(m) || ResourceBinder.PatternRules.MatchReferenceEquals(m) -- otherwise ProjectionAnalyzer should have blocked this for entities");
                if (m.Method.Name == "Select")
                {
                    result = this.RebindMethodCallForMemberSelect(m);
                }
                else if (m.Method.Name == "ToList")
                {
                    result = this.RebindMethodCallForMemberToList(m);
                }
                else
                {
                    Debug.Assert(m.Method.Name == "ReferenceEquals", "We don't know how to handle this method, ProjectionAnalyzer updated?");
                    result = base.VisitMethodCall(m);
                }
            }
            else
            {
                if (ProjectionAnalyzer.IsMethodCallAllowedEntitySequence(m))
                {
                    result = this.RebindMethodCallForNewSequence(m);
                }
                else
                {
                    result = base.VisitMethodCall(m);
                }
            }

            return(result);
        }
Esempio n. 6
0
            internal override Expression VisitMethodCall(MethodCallExpression m)
            {
                if ((m.Object != null && IsDisallowedExpressionForMethodCall(m.Object)) ||
                    m.Arguments.Any(a => IsDisallowedExpressionForMethodCall(a)))
                {
                    throw new NotSupportedException(Strings.ALinq_ExpressionNotSupportedInProjection(this.type, m.ToString()));
                }

                if (ProjectionAnalyzer.IsMethodCallAllowedEntitySequence(m))
                {
                    CheckChainedSequence(m, this.type);

                    // allow selects for following pattern:
                    // Orders = c.Orders.Select(o=> new NarrowOrder {...}).ToList();
                    return(base.VisitMethodCall(m));
                }

                throw new NotSupportedException(Strings.ALinq_ExpressionNotSupportedInProjectionToEntity(this.type, m.ToString()));
            }
Esempio n. 7
0
            internal override Expression VisitMethodCall(MethodCallExpression m)
            {
                // We throw NotSupportedException when IsDisallowedExceptionForMethodCall() is true
                // or we have a method call on a non-entity type, for example c.MyCollectionComplexProperty.Select(...)
                if ((m.Object != null && (IsDisallowedExpressionForMethodCall(m.Object, this.context.Model) || !ClientTypeUtil.TypeOrElementTypeIsEntity(m.Object.Type))) ||
                    m.Arguments.Any(a => IsDisallowedExpressionForMethodCall(a, this.context.Model)) ||
                    (m.Object == null && !ClientTypeUtil.TypeOrElementTypeIsEntity(m.Arguments[0].Type)))
                {
                    throw new NotSupportedException(Strings.ALinq_ExpressionNotSupportedInProjection(this.type, m.ToString()));
                }

                if (ProjectionAnalyzer.IsMethodCallAllowedEntitySequence(m))
                {
                    CheckChainedSequence(m, this.type);

                    // allow selects for following pattern:
                    // Orders = c.Orders.Select(o=> new NarrowOrder {...}).ToList();
                    return(base.VisitMethodCall(m));
                }

                throw new NotSupportedException(Strings.ALinq_ExpressionNotSupportedInProjectionToEntity(this.type, m.ToString()));
            }
Esempio n. 8
0
            internal override Expression VisitMethodCall(MethodCallExpression m)
            {
                if ((m.Object != null && IsDisallowedExpressionForMethodCall(m.Object, this.context.Model)) ||
                    m.Arguments.Any(a => IsDisallowedExpressionForMethodCall(a, this.context.Model)))
                {
                    throw new NotSupportedException(Strings.ALinq_ExpressionNotSupportedInProjection(this.type, m.ToString()));
                }

                CheckChainedSequence(m, this.type);
                if (ProjectionAnalyzer.IsMethodCallAllowedEntitySequence(m))
                {
                    // allow IEnum.Select and IEnum.ToList even if entity type.
                    return(base.VisitMethodCall(m));
                }

                if ((m.Object != null ? ClientTypeUtil.TypeOrElementTypeIsEntity(m.Object.Type) : false) ||
                    m.Arguments.Any(a => ClientTypeUtil.TypeOrElementTypeIsEntity(a.Type)))
                {
                    throw new NotSupportedException(Strings.ALinq_ExpressionNotSupportedInProjection(this.type, m.ToString()));
                }

                return(base.VisitMethodCall(m));
            }