protected override ShapedQueryExpression TranslateAll(ShapedQueryExpression source, LambdaExpression predicate) { var selectExpression = (SelectExpression)source.QueryExpression; if (selectExpression.Limit != null || selectExpression.Offset != null) { selectExpression.PushdownIntoSubQuery(); } var translation = TranslateLambdaExpression(source, predicate); if (translation != null) { selectExpression.ApplyPredicate(_sqlExpressionFactory.Not(translation)); selectExpression.ReplaceProjection(new Dictionary <ProjectionMember, Expression>()); if (selectExpression.Limit == null && selectExpression.Offset == null) { selectExpression.ClearOrdering(); } translation = _sqlExpressionFactory.Exists(selectExpression, true); source.QueryExpression = _sqlExpressionFactory.Select(translation); source.ShaperExpression = new ProjectionBindingExpression(source.QueryExpression, new ProjectionMember(), typeof(bool)); return(source); } throw new InvalidOperationException(); }
protected override ShapedQueryExpression CreateShapedQueryExpression(Type elementType) { var entityType = _model.FindEntityType(elementType); var queryExpression = _sqlExpressionFactory.Select(entityType); return(CreateShapedQueryExpression(entityType, queryExpression)); }
protected override ShapedQueryExpression CreateShapedQueryExpression(Type elementType) { Check.NotNull(elementType, nameof(elementType)); var entityType = _model.FindEntityType(elementType); var selectExpression = _sqlExpressionFactory.Select(entityType); return(new ShapedQueryExpression( selectExpression, new EntityShaperExpression( entityType, new ProjectionBindingExpression( selectExpression, new ProjectionMember(), typeof(ValueBuffer)), false))); }
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 && navigation.ForeignKey.IsOwnership) { 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); }