public override Expression Visit(Expression expression) { if (expression == null) { return(null); } if (!(expression is NewExpression || expression is MemberInitExpression || expression is EntityShaperExpression)) { // This skips the group parameter from GroupJoin if (expression is ParameterExpression parameter && parameter.Type.IsGenericType && parameter.Type.GetGenericTypeDefinition() == typeof(IEnumerable <>)) { return(parameter); } if (_clientEval) { if (expression is ConstantExpression) { return(expression); } if (expression is ParameterExpression parameterExpression) { return(Expression.Call( _getParameterValueMethodInfo.MakeGenericMethod(parameterExpression.Type), QueryCompilationContext2.QueryContextParameter, Expression.Constant(parameterExpression.Name))); } var translation = _sqlTranslator.Translate(expression); if (translation == null) { return(base.Visit(expression)); } else { return(_selectExpression.AddToProjection(translation, expression.Type)); } } else { var translation = _sqlTranslator.Translate(expression); if (translation == null) { return(null); } _projectionMapping[_projectionMembers.Peek()] = translation; return(new ProjectionBindingExpression(_selectExpression, _projectionMembers.Peek(), expression.Type)); } } return(base.Visit(expression)); }
private Expression TranslateGroupingKey(Expression expression) { if (expression is 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)); } if (expression is 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)); } return(_sqlTranslator.Translate(expression)); }
public override Expression Visit(Expression expression) { if (expression == null) { return(null); } if (!(expression is NewExpression || expression is MemberInitExpression || expression is EntityShaperExpression)) { // This skips the group parameter from GroupJoin if (expression is ParameterExpression parameter && parameter.Type.IsGenericType && parameter.Type.GetGenericTypeDefinition() == typeof(IEnumerable <>)) { return(parameter); } // This converts object[] from GetDatabaseValues to appropriate projection. if (expression is NewArrayExpression newArrayExpression && newArrayExpression.NodeType == ExpressionType.NewArrayInit && newArrayExpression.Expressions.Count > 0 && newArrayExpression.Expressions[0] is UnaryExpression unaryExpression && unaryExpression.NodeType == ExpressionType.Convert && unaryExpression.Type == typeof(object) && unaryExpression.Operand is MethodCallExpression methodCall && methodCall.Method.IsEFPropertyMethod() && methodCall.Arguments[0] is EntityShaperExpression entityShaperExpression && entityShaperExpression.EntityType.GetProperties().Count() == newArrayExpression.Expressions.Count) { VerifySelectExpression(entityShaperExpression.ValueBufferExpression); _projectionMapping[_projectionMembers.Peek()] = _selectExpression.GetProjectionExpression( entityShaperExpression.ValueBufferExpression.ProjectionMember); return(new EntityValuesExpression(entityShaperExpression.EntityType, entityShaperExpression.ValueBufferExpression)); } var translation = _sqlTranslator.Translate(expression); _projectionMapping[_projectionMembers.Peek()] = translation ?? throw new InvalidOperationException(); return(new ProjectionBindingExpression(_selectExpression, _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) { if (expression is ConstantExpression) { return(expression); } if (expression is ParameterExpression parameterExpression) { return(Expression.Call( _getParameterValueMethodInfo.MakeGenericMethod(parameterExpression.Type), QueryCompilationContext.QueryContextParameter, Expression.Constant(parameterExpression.Name))); } if (expression is MaterializeCollectionNavigationExpression materializeCollectionNavigationExpression) { return(_selectExpression.AddCollectionProjection( _queryableMethodTranslatingExpressionVisitor.TranslateSubquery( materializeCollectionNavigationExpression.Subquery), materializeCollectionNavigationExpression.Navigation, null)); } if (expression is 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)); } var subquery = _queryableMethodTranslatingExpressionVisitor.TranslateSubquery(methodCallExpression); if (subquery != null) { if (subquery.ResultType == ResultType.Enumerable) { return(_selectExpression.AddCollectionProjection(subquery, null, subquery.ShaperExpression.Type)); } } } var translation = _sqlTranslator.Translate(expression); if (translation == null) { return(base.Visit(expression)); } else { return(new ProjectionBindingExpression(_selectExpression, _selectExpression.AddToProjection(translation), expression.Type)); } } else { var translation = _sqlTranslator.Translate(expression); if (translation == null) { return(null); } _projectionMapping[_projectionMembers.Peek()] = translation; return(new ProjectionBindingExpression(_selectExpression, _projectionMembers.Peek(), expression.Type)); } } return(base.Visit(expression)); }
private SqlExpression TranslateExpression(Expression expression) { return(_sqlTranslator.Translate(expression)); }
private SqlExpression TranslateExpression(SelectExpression selectExpression, Expression expression) { return(_sqlTranslator.Translate(selectExpression, 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) { if (expression is ConstantExpression) { return(expression); } if (expression is ParameterExpression parameterExpression) { return(Expression.Call( _getParameterValueMethodInfo.MakeGenericMethod(parameterExpression.Type), QueryCompilationContext.QueryContextParameter, Expression.Constant(parameterExpression.Name))); } if (expression is MethodCallExpression methodCallExpression && methodCallExpression.Method.Name == "MaterializeCollectionNavigation") { var result = _queryableMethodTranslatingExpressionVisitor.TranslateSubquery(methodCallExpression.Arguments[0]); var navigation = (INavigation)((ConstantExpression)methodCallExpression.Arguments[1]).Value; return(_selectExpression.AddCollectionProjection(result, navigation)); } var translation = _sqlTranslator.Translate(expression); if (translation == null) { return(base.Visit(expression)); } else { return(_selectExpression.AddToProjection(translation, expression.Type)); } } else { var translation = _sqlTranslator.Translate(expression); if (translation == null) { return(null); } _projectionMapping[_projectionMembers.Peek()] = translation; return(new ProjectionBindingExpression(_selectExpression, _projectionMembers.Peek(), expression.Type)); } } return(base.Visit(expression)); }
private Expression Expand(Expression source, MemberIdentity member) { Type convertedType = null; if (source is UnaryExpression unaryExpression && unaryExpression.NodeType == ExpressionType.Convert) { source = unaryExpression.Operand; if (unaryExpression.Type != typeof(object)) { convertedType = unaryExpression.Type; } } if (source is EntityShaperExpression entityShaperExpression) { var entityType = entityShaperExpression.EntityType; if (convertedType != null) { entityType = entityType.RootType().GetDerivedTypesInclusive() .FirstOrDefault(et => et.ClrType == convertedType); if (entityType == null) { return(null); } } var navigation = member.MemberInfo != null ? entityType.FindNavigation(member.MemberInfo) : entityType.FindNavigation(member.Name); if (navigation != null) { if (navigation.IsCollection()) { return(CreateShapedQueryExpression( navigation.GetTargetType(), _sqlExpressionFactory.Select(navigation.GetTargetType()))); } var entityProjectionExpression = (EntityProjectionExpression) (entityShaperExpression.ValueBufferExpression is ProjectionBindingExpression projectionBindingExpression ? _selectExpression.GetMappedProjection(projectionBindingExpression.ProjectionMember) : entityShaperExpression.ValueBufferExpression); var innerShaper = entityProjectionExpression.BindNavigation(navigation); if (innerShaper == null) { var targetEntityType = navigation.GetTargetType(); var innerSelectExpression = _sqlExpressionFactory.Select(targetEntityType); var innerShapedQuery = CreateShapedQueryExpression(targetEntityType, innerSelectExpression); var makeNullable = navigation.ForeignKey.PrincipalKey.Properties .Concat(navigation.ForeignKey.Properties) .Select(p => p.ClrType) .Any(t => t.IsNullableType()); var outerKey = CreateKeyAccessExpression( entityShaperExpression, navigation.ForeignKey.PrincipalKey.Properties, makeNullable); var innerKey = CreateKeyAccessExpression( innerShapedQuery.ShaperExpression, navigation.ForeignKey.Properties, makeNullable); var joinPredicate = _sqlTranslator.Translate(Expression.Equal(outerKey, innerKey)); _selectExpression.AddLeftJoin(innerSelectExpression, joinPredicate, null); var leftJoinTable = ((LeftJoinExpression)_selectExpression.Tables.Last()).Table; innerShaper = new EntityShaperExpression(targetEntityType, new EntityProjectionExpression(targetEntityType, leftJoinTable, true), true); entityProjectionExpression.AddNavigationBinding(navigation, innerShaper); } return(innerShaper); } } return(null); }