Example #1
0
        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));
        }
Example #3
0
        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);
        }