/// <summary> /// If there is a MemberInitExpression 'new Person { ID = p.ID, Friend = new Person { ID = p.Friend.ID }}' /// or a NewExpression 'new { ID = p.ID, Friend = new { ID = p.Friend.ID }}', /// this method validates against the RHS of the member assigment, the expression "p.ID" for example. /// </summary> /// <param name="expressionToAssign">The expression to validate.</param> /// <param name="initType">Type of the MemberInit or the New expression.</param> /// <param name="previousNested">The outter nested initializer of the current initializer we are checking.</param> /// <returns>true if the expression to assign is fine; false otherwise.</returns> private bool CheckCompatibleAssigmentExpression(Expression expressionToAssign, Type initType, ref MemberAssignmentAnalysis previousNested) { MemberAssignmentAnalysis nested = MemberAssignmentAnalysis.Analyze(this.entity, expressionToAssign); if (nested.MultiplePathsFound) { this.multiplePathsFound = true; return(false); } // When we're visitng a nested entity initializer, we're exactly one level above that. Exception incompatibleException = nested.CheckCompatibleAssignments(initType, ref previousNested); if (incompatibleException != null) { this.incompatibleAssignmentsException = incompatibleException; return(false); } if (this.pathFromEntity.Count == 0) { this.pathFromEntity.AddRange(nested.GetExpressionsToTargetEntity()); } return(true); }
internal override Expression VisitMemberInit(MemberInitExpression init) { Expression result = init; MemberAssignmentAnalysis previousNested = null; foreach (var binding in init.Bindings) { MemberAssignment assignment = binding as MemberAssignment; if (assignment == null) { continue; } MemberAssignmentAnalysis nested = MemberAssignmentAnalysis.Analyze(this.entity, assignment.Expression); if (nested.MultiplePathsFound) { this.multiplePathsFound = true; break; } Exception incompatibleException = nested.CheckCompatibleAssignments(init.Type, ref previousNested); if (incompatibleException != null) { this.incompatibleAssignmentsException = incompatibleException; break; } if (this.pathFromEntity.Count == 0) { this.pathFromEntity.AddRange(nested.GetExpressionsToTargetEntity()); } } return(result); }
internal static void Analyze(MemberInitExpression mie, PathBox pb, DataServiceContext context) { ProjectionAnalyzer.EntityProjectionAnalyzer analyzer = new ProjectionAnalyzer.EntityProjectionAnalyzer(pb, mie.Type, context); MemberAssignmentAnalysis previous = null; foreach (MemberBinding binding in mie.Bindings) { MemberAssignment assignment = binding as MemberAssignment; analyzer.Visit(assignment.Expression); if (assignment != null) { MemberAssignmentAnalysis analysis2 = MemberAssignmentAnalysis.Analyze(pb.ParamExpressionInScope, assignment.Expression); if (analysis2.IncompatibleAssignmentsException != null) { throw analysis2.IncompatibleAssignmentsException; } Type memberType = ClientTypeUtil.GetMemberType(assignment.Member); Expression[] expressionsBeyondTargetEntity = analysis2.GetExpressionsBeyondTargetEntity(); if (expressionsBeyondTargetEntity.Length == 0) { throw new NotSupportedException(System.Data.Services.Client.Strings.ALinq_ExpressionNotSupportedInProjectionToEntity(memberType, assignment.Expression)); } MemberExpression expression = expressionsBeyondTargetEntity[expressionsBeyondTargetEntity.Length - 1] as MemberExpression; analysis2.CheckCompatibleAssignments(mie.Type, ref previous); if (expression != null) { if (expression.Member.Name != assignment.Member.Name) { throw new NotSupportedException(System.Data.Services.Client.Strings.ALinq_PropertyNamesMustMatchInProjections(expression.Member.Name, assignment.Member.Name)); } bool flag = ClientTypeUtil.TypeOrElementTypeIsEntity(memberType); if (ClientTypeUtil.TypeOrElementTypeIsEntity(expression.Type) && !flag) { throw new NotSupportedException(System.Data.Services.Client.Strings.ALinq_ExpressionNotSupportedInProjection(memberType, assignment.Expression)); } } } } }
private bool CheckCompatibleAssigmentExpression(Expression expressionToAssign, Type initType, ref MemberAssignmentAnalysis previousNested) { MemberAssignmentAnalysis analysis = Analyze(this.entity, expressionToAssign); if (analysis.MultiplePathsFound) { this.multiplePathsFound = true; return(false); } Exception exception = analysis.CheckCompatibleAssignments(initType, ref previousNested); if (exception != null) { this.incompatibleAssignmentsException = exception; return(false); } if (this.pathFromEntity.Count == 0) { this.pathFromEntity.AddRange(analysis.GetExpressionsToTargetEntity()); } return(true); }