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(); }
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); }