protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) { QueryJoinClause o = other as QueryJoinClause; return(o != null && this.IsGroupJoin == o.IsGroupJoin && this.Type.DoMatch(o.Type, match) && MatchString(this.JoinIdentifier, o.JoinIdentifier) && this.InExpression.DoMatch(o.InExpression, match) && this.OnExpression.DoMatch(o.OnExpression, match) && this.EqualsExpression.DoMatch(o.EqualsExpression, match) && MatchString(this.IntoIdentifier, o.IntoIdentifier)); }
S IAstVisitor <T, S> .VisitQueryJoinClause(QueryJoinClause queryJoinClause, T data) { var handler = QueryJoinClauseVisited; if (handler != null) { handler(queryJoinClause, data); } return(VisitChildren(queryJoinClause, data)); }
public override AstNode VisitQueryJoinClause(QueryJoinClause queryJoinClause) { Expression resultSelectorBody = null; var inExpression = VisitNested(queryJoinClause.InExpression, null); if (!queryJoinClause.Type.IsNull) { inExpression = inExpression.Invoke("Cast", new[] { queryJoinClause.Type.Clone() }, EmptyList <Expression> .Instance); } var key1SelectorFirstParam = CreateParameterForCurrentRangeVariable(); var key1Selector = CreateLambda(new[] { key1SelectorFirstParam }, VisitNested(queryJoinClause.OnExpression, key1SelectorFirstParam)); var key2Param = CreateParameter(Identifier.Create(queryJoinClause.JoinIdentifier)); var key2Selector = CreateLambda(new[] { key2Param }, VisitNested(queryJoinClause.EqualsExpression, null)); var resultSelectorFirstParam = CreateParameterForCurrentRangeVariable(); var select = GetNextQueryClause(queryJoinClause) as QuerySelectClause; if (select != null) { resultSelectorBody = VisitNested(select.Expression, resultSelectorFirstParam); eatSelect = true; } if (queryJoinClause.IntoKeyword.IsNull) { // Normal join if (resultSelectorBody == null) { resultSelectorBody = AddMemberToCurrentTransparentType(resultSelectorFirstParam, queryJoinClause.JoinIdentifierToken, new IdentifierExpression(queryJoinClause.JoinIdentifier), false); } var resultSelector = CreateLambda(new[] { resultSelectorFirstParam, CreateParameter(Identifier.Create(queryJoinClause.JoinIdentifier)) }, resultSelectorBody); rangeVariables[queryJoinClause.JoinIdentifierToken] = key2Param; return(currentResult.Invoke("Join", inExpression, key1Selector, key2Selector, resultSelector)); } else { // Group join if (resultSelectorBody == null) { resultSelectorBody = AddMemberToCurrentTransparentType(resultSelectorFirstParam, queryJoinClause.IntoIdentifierToken, new IdentifierExpression(queryJoinClause.IntoIdentifier), false); } var intoParam = CreateParameter(Identifier.Create(queryJoinClause.IntoIdentifier)); var resultSelector = CreateLambda(new[] { resultSelectorFirstParam, intoParam }, resultSelectorBody); rangeVariables[queryJoinClause.IntoIdentifierToken] = intoParam; return(currentResult.Invoke("GroupJoin", inExpression, key1Selector, key2Selector, resultSelector)); } }
QueryExpression DecompileQuery(InvocationExpression invocation) { if (invocation == null) { return(null); } MemberReferenceExpression mre = invocation.Target as MemberReferenceExpression; if (mre == null) { return(null); } switch (mre.MemberName) { case "Select": { if (invocation.Arguments.Count != 1) { return(null); } string parameterName; Expression body; if (MatchSimpleLambda(invocation.Arguments.Single(), out parameterName, out body)) { QueryExpression query = new QueryExpression(); query.Clauses.Add(new QueryFromClause { Identifier = parameterName, Expression = ExtractQuery(mre) }); query.Clauses.Add(new QuerySelectClause { Expression = body.Detach() }); return(query); } return(null); } case "Cast": { if (invocation.Arguments.Count == 0 && mre.TypeArguments.Count == 1) { var typeArgument = mre.TypeArguments.First(); QueryExpression query = new QueryExpression(); string varName = GenerateVariableName(); query.Clauses.Add(new QueryFromClause { Identifier = varName, Expression = ExtractQuery(mre), Type = typeArgument.Detach() }); return(query); } return(null); } case "GroupBy": { if (invocation.Arguments.Count == 2) { string parameterName1, parameterName2; Expression keySelector, elementSelector; if (MatchSimpleLambda(invocation.Arguments.ElementAt(0), out parameterName1, out keySelector) && MatchSimpleLambda(invocation.Arguments.ElementAt(1), out parameterName2, out elementSelector) && parameterName1 == parameterName2) { QueryExpression query = new QueryExpression(); query.Clauses.Add(new QueryFromClause { Identifier = parameterName1, Expression = ExtractQuery(mre) }); query.Clauses.Add(new QueryGroupClause { Projection = elementSelector.Detach(), Key = keySelector.Detach() }); return(query); } } else if (invocation.Arguments.Count == 1) { string parameterName; Expression keySelector; if (MatchSimpleLambda(invocation.Arguments.Single(), out parameterName, out keySelector)) { QueryExpression query = new QueryExpression(); query.Clauses.Add(new QueryFromClause { Identifier = parameterName, Expression = ExtractQuery(mre) }); query.Clauses.Add(new QueryGroupClause { Projection = new IdentifierExpression(parameterName), Key = keySelector.Detach() }); return(query); } } return(null); } case "SelectMany": { if (invocation.Arguments.Count != 2) { return(null); } string parameterName; Expression collectionSelector; if (!MatchSimpleLambda(invocation.Arguments.ElementAt(0), out parameterName, out collectionSelector)) { return(null); } LambdaExpression lambda = invocation.Arguments.ElementAt(1) as LambdaExpression; if (lambda != null && lambda.Parameters.Count == 2 && lambda.Body is Expression) { ParameterDeclaration p1 = lambda.Parameters.ElementAt(0); ParameterDeclaration p2 = lambda.Parameters.ElementAt(1); QueryExpression query = new QueryExpression(); query.Clauses.Add(new QueryFromClause { Identifier = p1.Name, Expression = ExtractQuery(mre) }); query.Clauses.Add(new QueryFromClause { Identifier = p2.Name, Expression = collectionSelector.Detach() }); query.Clauses.Add(new QuerySelectClause { Expression = ((Expression)lambda.Body).Detach() }); return(query); } return(null); } case "Where": { if (invocation.Arguments.Count != 1) { return(null); } string parameterName; Expression body; if (MatchSimpleLambda(invocation.Arguments.Single(), out parameterName, out body)) { QueryExpression query = new QueryExpression(); query.Clauses.Add(new QueryFromClause { Identifier = parameterName, Expression = ExtractQuery(mre) }); query.Clauses.Add(new QueryWhereClause { Condition = body.Detach() }); return(query); } return(null); } case "OrderBy": case "OrderByDescending": case "ThenBy": case "ThenByDescending": { if (invocation.Arguments.Count != 1) { return(null); } string parameterName; Expression orderExpression; if (MatchSimpleLambda(invocation.Arguments.Single(), out parameterName, out orderExpression)) { if (ValidateThenByChain(invocation, parameterName)) { QueryOrderClause orderClause = new QueryOrderClause(); InvocationExpression tmp = invocation; while (mre.MemberName == "ThenBy" || mre.MemberName == "ThenByDescending") { // insert new ordering at beginning orderClause.Orderings.InsertAfter( null, new QueryOrdering { Expression = orderExpression.Detach(), Direction = (mre.MemberName == "ThenBy" ? QueryOrderingDirection.None : QueryOrderingDirection.Descending) }); tmp = (InvocationExpression)mre.Target; mre = (MemberReferenceExpression)tmp.Target; MatchSimpleLambda(tmp.Arguments.Single(), out parameterName, out orderExpression); } // insert new ordering at beginning orderClause.Orderings.InsertAfter( null, new QueryOrdering { Expression = orderExpression.Detach(), Direction = (mre.MemberName == "OrderBy" ? QueryOrderingDirection.None : QueryOrderingDirection.Descending) }); QueryExpression query = new QueryExpression(); query.Clauses.Add(new QueryFromClause { Identifier = parameterName, Expression = ExtractQuery(mre) }); query.Clauses.Add(orderClause); return(query); } } return(null); } case "Join": case "GroupJoin": { if (invocation.Arguments.Count != 4) { return(null); } Expression source1 = mre.Target; Expression source2 = invocation.Arguments.ElementAt(0); string elementName1, elementName2; Expression key1, key2; if (!MatchSimpleLambda(invocation.Arguments.ElementAt(1), out elementName1, out key1)) { return(null); } if (!MatchSimpleLambda(invocation.Arguments.ElementAt(2), out elementName2, out key2)) { return(null); } LambdaExpression lambda = invocation.Arguments.ElementAt(3) as LambdaExpression; if (lambda != null && lambda.Parameters.Count == 2 && lambda.Body is Expression) { ParameterDeclaration p1 = lambda.Parameters.ElementAt(0); ParameterDeclaration p2 = lambda.Parameters.ElementAt(1); QueryExpression query = new QueryExpression(); query.Clauses.Add(new QueryFromClause { Identifier = elementName1, Expression = source1.Detach() }); QueryJoinClause joinClause = new QueryJoinClause(); joinClause.JoinIdentifier = elementName2; // join elementName2 joinClause.InExpression = source2.Detach(); // in source2 Match castMatch = castPattern.Match(source2); if (castMatch.Success) { Expression target = castMatch.Get <Expression>("inExpr").Single().Detach(); joinClause.Type = castMatch.Get <AstType>("targetType").Single().Detach(); joinClause.InExpression = target; } joinClause.OnExpression = key1.Detach(); // on key1 joinClause.EqualsExpression = key2.Detach(); // equals key2 if (mre.MemberName == "GroupJoin") { joinClause.IntoIdentifier = p2.Name; // into p2.Name } query.Clauses.Add(joinClause); Expression resultExpr = ((Expression)lambda.Body).Detach(); if (p1.Name != elementName1) { foreach (var identifier in resultExpr.Descendants.OfType <Identifier>().Where(id => id.Name == p1.Name)) { identifier.Name = elementName1; } } if (p2.Name != elementName2 && mre.MemberName != "GroupJoin") { foreach (var identifier in resultExpr.Descendants.OfType <Identifier>().Where(id => id.Name == p2.Name)) { identifier.Name = elementName2; } } query.Clauses.Add(new QuerySelectClause { Expression = resultExpr }); return(query); } return(null); } default: return(null); } }
void IAstVisitor.VisitQueryJoinClause(QueryJoinClause queryJoinClause) { Visit(EnterQueryJoinClause, LeaveQueryJoinClause, queryJoinClause); }
public virtual S VisitQueryJoinClause(QueryJoinClause queryJoinClause, T data) { return(VisitChildren(queryJoinClause, data)); }
public override void VisitQueryJoinClause(QueryJoinClause queryJoinClause) { FixClauseIndentation(queryJoinClause, queryJoinClause.JoinKeyword); }
public virtual S VisitQueryJoinClause(QueryJoinClause queryJoinClause, T data) { throw new NotImplementedException(); }