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