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)); }
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); }
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)); }
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())); }
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); }
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())); }
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())); }
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)); }