protected override ShapedQueryExpression TranslateGroupBy(
            ShapedQueryExpression source,
            LambdaExpression keySelector,
            LambdaExpression elementSelector,
            LambdaExpression resultSelector)
        {
            var selectExpression = (SelectExpression)source.QueryExpression;

            selectExpression.PrepareForAggregate();

            var remappedKeySelector = RemapLambdaBody(source.ShaperExpression, keySelector);

            var translatedKey = TranslateGroupingKey(remappedKeySelector)
                                ?? (remappedKeySelector is ConstantExpression ? remappedKeySelector : null);

            if (translatedKey != null)
            {
                if (elementSelector != null)
                {
                    source = TranslateSelect(source, elementSelector);
                }

                var sqlKeySelector = translatedKey is ConstantExpression
                    ? _sqlExpressionFactory.ApplyDefaultTypeMapping(_sqlExpressionFactory.Constant(1))
                    : translatedKey;

                var appliedKeySelector = selectExpression.ApplyGrouping(sqlKeySelector);
                translatedKey = translatedKey is ConstantExpression ? translatedKey : appliedKeySelector;

                source.ShaperExpression = new GroupByShaperExpression(translatedKey, source.ShaperExpression);

                if (resultSelector == null)
                {
                    return(source);
                }

                var keyAccessExpression = Expression.MakeMemberAccess(
                    source.ShaperExpression,
                    source.ShaperExpression.Type.GetTypeInfo().GetMember(nameof(IGrouping <int, int> .Key))[0]);

                var newResultSelectorBody = ReplacingExpressionVisitor.Replace(
                    resultSelector.Parameters[0], keyAccessExpression,
                    resultSelector.Parameters[1], source.ShaperExpression,
                    resultSelector.Body);

                source.ShaperExpression = _projectionBindingExpressionVisitor.Translate(selectExpression, newResultSelectorBody);

                return(source);
            }

            throw new InvalidOperationException();
        }
コード例 #2
0
        protected override ShapedQueryExpression TranslateSelect(ShapedQueryExpression source, LambdaExpression selector)
        {
            if (selector.Body == selector.Parameters[0])
            {
                return(source);
            }

            var newSelectorBody = ReplacingExpressionVisitor.Replace(selector.Parameters.Single(), source.ShaperExpression, selector.Body);

            source.ShaperExpression = _projectionBindingExpressionVisitor
                                      .Translate((SelectExpression)source.QueryExpression, newSelectorBody);

            return(source);
        }