private CodeExpression VisitJoinExpressionBase(LinqJoinExpressionBase expression, string codeMethodName) { var outer = this.GenerateCode(expression.Outer); var inner = this.GenerateCode(expression.Inner); var outerKeySelector = this.GenerateCode(expression.OuterKeySelector); var innerKeySelector = this.GenerateCode(expression.InnerKeySelector); var resultSelector = this.GenerateCode(expression.ResultSelector); return(outer.Call(codeMethodName, inner, outerKeySelector, innerKeySelector, resultSelector)); }
private QueryValue EvaluateJoinExpression(LinqJoinExpressionBase expression, bool isGroupJoin) { var outer = this.EvaluateCollection(expression.Outer); var inner = this.EvaluateCollection(expression.Inner); var outerKeys = this.EvaluateKeysForJoin(outer, expression.OuterKeySelector); var innerKeys = this.EvaluateKeysForJoin(inner, expression.InnerKeySelector); // Dictionary: inner key -> a list of inner values with this key Dictionary <QueryScalarValue, IList <QueryValue> > innerKeyLookup = this.BuildInnerKeyLookup(inner, innerKeys); List <QueryValue> joinResultElements = new List <QueryValue>(); for (int outerIndex = 0; outerIndex < outer.Elements.Count; outerIndex++) { ExceptionUtilities.Assert(outerKeys.Elements[outerIndex] is QueryScalarValue, "For now we only support join on primitive keys."); var outerKey = (QueryScalarValue)outerKeys.Elements[outerIndex]; IList <QueryValue> innerMatches; if (!innerKeyLookup.TryGetValue(outerKey, out innerMatches)) { innerMatches = new List <QueryValue>(); } if (isGroupJoin) { QueryValue result = this.EvaluateLambda <QueryValue>(expression.ResultSelector, outer.Elements[outerIndex], inner.Type.CreateCollectionWithValues(innerMatches)); joinResultElements.Add(result); } else { foreach (var innerValue in innerMatches) { QueryValue result = this.EvaluateLambda <QueryValue>(expression.ResultSelector, outer.Elements[outerIndex], innerValue); joinResultElements.Add(result); } } } var resultType = expression.ResultSelector.Body.ExpressionType; return(new QueryCollectionValue(resultType.CreateCollectionType(), resultType.EvaluationStrategy, QueryError.GetErrorFromValues(joinResultElements), joinResultElements)); }
private QueryExpression VisitJoinExpressionBase(LinqJoinExpressionBase expression, Func <QueryExpression, QueryExpression, LinqLambdaExpression, LinqLambdaExpression, LinqLambdaExpression, QueryType, QueryExpression> builderFunc) { var outer = this.ReplaceExpression(expression.Outer); var inner = this.ReplaceExpression(expression.Inner); var outerKeySelector = (LinqLambdaExpression)this.ReplaceExpression(expression.OuterKeySelector); var innerKeySelector = (LinqLambdaExpression)this.ReplaceExpression(expression.InnerKeySelector); var resultSelector = (LinqLambdaExpression)this.ReplaceExpression(expression.ResultSelector); if (HasChanged(expression.Outer, outer) || HasChanged(expression.Inner, inner) || HasChanged(expression.OuterKeySelector, outerKeySelector) || HasChanged(expression.InnerKeySelector, innerKeySelector) || HasChanged(expression.ResultSelector, resultSelector)) { return(builderFunc(outer, inner, outerKeySelector, innerKeySelector, resultSelector, expression.ExpressionType)); } return(expression); }