private Expression TranslateGroupingKey(Expression expression) { switch (expression) { case NewExpression newExpression: if (newExpression.Arguments.Count == 0) { return(newExpression); } var newArguments = new Expression[newExpression.Arguments.Count]; for (var i = 0; i < newArguments.Length; i++) { newArguments[i] = TranslateGroupingKey(newExpression.Arguments[i]); if (newArguments[i] == null) { return(null); } } return(newExpression.Update(newArguments)); case MemberInitExpression memberInitExpression: var updatedNewExpression = (NewExpression)TranslateGroupingKey(memberInitExpression.NewExpression); if (updatedNewExpression == null) { return(null); } var newBindings = new MemberAssignment[memberInitExpression.Bindings.Count]; for (var i = 0; i < newBindings.Length; i++) { var memberAssignment = (MemberAssignment)memberInitExpression.Bindings[i]; var visitedExpression = TranslateGroupingKey(memberAssignment.Expression); if (visitedExpression == null) { return(null); } newBindings[i] = memberAssignment.Update(visitedExpression); } return(memberInitExpression.Update(updatedNewExpression, newBindings)); default: var translation = _expressionTranslator.Translate(expression); if (translation == null) { return(null); } return(translation.Type == expression.Type ? (Expression)translation : Expression.Convert(translation, expression.Type)); } }
public override Expression Visit(Expression expression) { if (expression == null) { return(null); } if (!(expression is NewExpression || expression is MemberInitExpression || expression is EntityShaperExpression || expression is IncludeExpression)) { // This skips the group parameter from GroupJoin if (expression is ParameterExpression parameter && parameter.Type.IsGenericType && parameter.Type.GetGenericTypeDefinition() == typeof(IEnumerable <>)) { return(parameter); } if (_clientEval) { switch (expression) { case ConstantExpression _: return(expression); case MaterializeCollectionNavigationExpression materializeCollectionNavigationExpression: //return _selectExpression.AddCollectionProjection( // _queryableMethodTranslatingExpressionVisitor.TranslateSubquery( // materializeCollectionNavigationExpression.Subquery), // materializeCollectionNavigationExpression.Navigation, null); throw new NotImplementedException(); case MethodCallExpression methodCallExpression: { if (methodCallExpression.Method.IsGenericMethod && methodCallExpression.Method.DeclaringType == typeof(Enumerable) && methodCallExpression.Method.Name == nameof(Enumerable.ToList)) { //var elementType = methodCallExpression.Method.GetGenericArguments()[0]; //var result = _queryableMethodTranslatingExpressionVisitor.TranslateSubquery(methodCallExpression.Arguments[0]); //return _selectExpression.AddCollectionProjection(result, null, elementType); throw new NotImplementedException(); } var subquery = _queryableMethodTranslatingExpressionVisitor.TranslateSubquery(methodCallExpression); if (subquery != null) { //if (subquery.ResultType == ResultType.Enumerable) //{ // return _selectExpression.AddCollectionProjection(subquery, null, subquery.ShaperExpression.Type); //} throw new NotImplementedException(); } break; } } var translation = _expressionTranslatingExpressionVisitor.Translate(expression); return(translation == null ? base.Visit(expression) : new ProjectionBindingExpression(_queryExpression, _queryExpression.AddToProjection(translation), expression.Type)); } else { var translation = _expressionTranslatingExpressionVisitor.Translate(expression); if (translation == null) { return(null); } _projectionMapping[_projectionMembers.Peek()] = translation; return(new ProjectionBindingExpression(_queryExpression, _projectionMembers.Peek(), expression.Type)); } } return(base.Visit(expression)); }
public override Expression?Visit(Expression?expression) { if (expression == null) { return(null); } if (!(expression is NewExpression || expression is MemberInitExpression || expression is EntityShaperExpression || expression is IncludeExpression)) { // This skips the group parameter from GroupJoin if (expression is ParameterExpression parameter && parameter.Type.IsGenericType && parameter.Type.GetGenericTypeDefinition() == typeof(IEnumerable <>)) { return(parameter); } if (_clientEval) { switch (expression) { case ConstantExpression _: return(expression); case MaterializeCollectionNavigationExpression materializeCollectionNavigationExpression: return(AddCollectionProjection( _queryableMethodTranslatingExpressionVisitor.TranslateSubquery( materializeCollectionNavigationExpression.Subquery) !, materializeCollectionNavigationExpression.Navigation, materializeCollectionNavigationExpression.Navigation.ClrType.GetSequenceType())); case MethodCallExpression methodCallExpression: { if (methodCallExpression.Method.IsGenericMethod && methodCallExpression.Method.DeclaringType == typeof(Enumerable) && methodCallExpression.Method.Name == nameof(Enumerable.ToList)) { var subqueryTranslation = _queryableMethodTranslatingExpressionVisitor.TranslateSubquery( methodCallExpression.Arguments[0]); if (subqueryTranslation != null) { return(AddCollectionProjection( subqueryTranslation, null, methodCallExpression.Method.GetGenericArguments()[0])); } } else { var subquery = _queryableMethodTranslatingExpressionVisitor.TranslateSubquery(methodCallExpression); if (subquery != null) { if (subquery.ResultCardinality == ResultCardinality.Enumerable) { return(AddCollectionProjection(subquery, null, subquery.ShaperExpression.Type)); } return(new SingleResultShaperExpression( new ProjectionBindingExpression( _queryExpression, _queryExpression.AddSubqueryProjection(subquery, out var innerShaper), typeof(ValueBuffer)), innerShaper, subquery.ShaperExpression.Type)); } } break; } } var translation = _expressionTranslatingExpressionVisitor.Translate(expression); return(translation == null ? base.Visit(expression) : new ProjectionBindingExpression( _queryExpression, _queryExpression.AddToProjection(translation), expression.Type.MakeNullable())); } else { var translation = _expressionTranslatingExpressionVisitor.Translate(expression); if (translation == null) { return(QueryCompilationContext.NotTranslatedExpression); } _projectionMapping[_projectionMembers.Peek()] = translation; return(new ProjectionBindingExpression(_queryExpression, _projectionMembers.Peek(), expression.Type.MakeNullable())); } } return(base.Visit(expression)); }
private Expression TranslateExpression(Expression expression) { return(_expressionTranslator.Translate(expression)); }