Example #1
0
        protected override ShapedQueryExpression TranslateSelectMany(
            ShapedQueryExpression source, LambdaExpression collectionSelector, LambdaExpression resultSelector)
        {
            var collectionSelectorBody = collectionSelector.Body;

            //var defaultIfEmpty = false;

            if (collectionSelectorBody is MethodCallExpression collectionEndingMethod &&
                collectionEndingMethod.Method.IsGenericMethod &&
                collectionEndingMethod.Method.GetGenericMethodDefinition() == _defaultIfEmptyWithoutArgMethodInfo)
            {
                //defaultIfEmpty = true;
                collectionSelectorBody = collectionEndingMethod.Arguments[0];
            }

            var correlated = new CorrelationFindingExpressionVisitor().IsCorrelated(collectionSelectorBody, collectionSelector.Parameters[0]);

            if (correlated)
            {
                // TODO visit inner with outer parameter;
                // See #17236
                throw new InvalidOperationException(CoreStrings.TranslationFailed(
                                                        collectionSelector.Print() + "; " + resultSelector.Print()));
            }
            else
            {
                if (Visit(collectionSelectorBody) is ShapedQueryExpression inner)
                {
                    var transparentIdentifierType = TransparentIdentifierFactory.Create(
                        resultSelector.Parameters[0].Type,
                        resultSelector.Parameters[1].Type);

                    ((InMemoryQueryExpression)source.QueryExpression).AddCrossJoin(
                        (InMemoryQueryExpression)inner.QueryExpression, transparentIdentifierType);

                    return(TranslateResultSelectorForJoin(
                               source,
                               resultSelector,
                               inner.ShaperExpression,
                               transparentIdentifierType));
                }
            }

            throw new NotImplementedException();
        }
        protected override ShapedQueryExpression TranslateSelectMany(ShapedQueryExpression source, LambdaExpression collectionSelector, LambdaExpression resultSelector)
        {
            var collectionSelectorBody = collectionSelector.Body;

            //var defaultIfEmpty = false;

            if (collectionSelectorBody is MethodCallExpression collectionEndingMethod &&
                collectionEndingMethod.Method.IsGenericMethod &&
                collectionEndingMethod.Method.GetGenericMethodDefinition() == _defaultIfEmptyWithoutArgMethodInfo)
            {
                //defaultIfEmpty = true;
                collectionSelectorBody = collectionEndingMethod.Arguments[0];
            }

            var correlated = new CorrelationFindingExpressionVisitor().IsCorrelated(collectionSelectorBody, collectionSelector.Parameters[0]);

            if (correlated)
            {
                // TODO visit inner with outer parameter;
                throw new NotImplementedException();
            }
            else
            {
                if (Visit(collectionSelectorBody) is ShapedQueryExpression inner)
                {
                    var outerSelectExpression = (SelectExpression)source.QueryExpression;
                    if (outerSelectExpression.Limit != null ||
                        outerSelectExpression.Offset != null ||
                        outerSelectExpression.IsDistinct ||
                        outerSelectExpression.Predicate != null)
                    {
                        outerSelectExpression.PushdownIntoSubQuery();
                    }

                    var innerSelectExpression = (SelectExpression)inner.QueryExpression;
                    if (innerSelectExpression.Orderings.Any() ||
                        innerSelectExpression.Limit != null ||
                        innerSelectExpression.Offset != null ||
                        innerSelectExpression.IsDistinct ||
                        innerSelectExpression.Predicate != null)
                    {
                        innerSelectExpression.PushdownIntoSubQuery();
                    }

                    var transparentIdentifierType = CreateTransparentIdentifierType(
                        resultSelector.Parameters[0].Type,
                        resultSelector.Parameters[1].Type);

                    outerSelectExpression.AddCrossJoin(
                        innerSelectExpression, transparentIdentifierType);

                    return(TranslateResultSelectorForJoin(
                               source,
                               resultSelector,
                               inner.ShaperExpression,
                               transparentIdentifierType,
                               false));
                }
            }

            throw new NotImplementedException();
        }
Example #3
0
        protected override ShapedQueryExpression TranslateSelectMany(
            ShapedQueryExpression source, LambdaExpression collectionSelector, LambdaExpression resultSelector)
        {
            var(newCollectionSelector, correlated, defaultIfEmpty)
                = new CorrelationFindingExpressionVisitor().IsCorrelated(collectionSelector);
            if (correlated)
            {
                var collectionSelectorBody = RemapLambdaBody(source, newCollectionSelector);
                if (Visit(collectionSelectorBody) is ShapedQueryExpression inner)
                {
                    var transparentIdentifierType = TransparentIdentifierFactory.Create(
                        resultSelector.Parameters[0].Type,
                        resultSelector.Parameters[1].Type);

                    var innerShaperExpression = inner.ShaperExpression;
                    if (defaultIfEmpty)
                    {
                        ((SelectExpression)source.QueryExpression).AddOuterApply(
                            (SelectExpression)inner.QueryExpression, transparentIdentifierType);
                        innerShaperExpression = MarkShaperNullable(innerShaperExpression);
                    }
                    else
                    {
                        ((SelectExpression)source.QueryExpression).AddCrossApply(
                            (SelectExpression)inner.QueryExpression, transparentIdentifierType);
                    }

                    return(TranslateResultSelectorForJoin(
                               source,
                               resultSelector,
                               innerShaperExpression,
                               transparentIdentifierType));
                }
            }
            else
            {
                if (Visit(newCollectionSelector.Body) is ShapedQueryExpression inner)
                {
                    if (defaultIfEmpty)
                    {
                        inner = TranslateDefaultIfEmpty(inner, null);
                        if (inner == null)
                        {
                            return(null);
                        }
                    }

                    var transparentIdentifierType = TransparentIdentifierFactory.Create(
                        resultSelector.Parameters[0].Type,
                        resultSelector.Parameters[1].Type);

                    ((SelectExpression)source.QueryExpression).AddCrossJoin(
                        (SelectExpression)inner.QueryExpression, transparentIdentifierType);

                    return(TranslateResultSelectorForJoin(
                               source,
                               resultSelector,
                               inner.ShaperExpression,
                               transparentIdentifierType));
                }
            }

            return(null);
        }