/// <summary> /// Visits a query source reference expression. /// </summary> /// <param name="expression"> The expression to visit. </param> /// <returns> /// An Expression. /// </returns> protected override Expression VisitQuerySourceReference(QuerySourceReferenceExpression expression) { Check.NotNull(expression, nameof(expression)); if (!_inProjection) { var joinClause = expression.ReferencedQuerySource as JoinClause; if (joinClause != null) { var entityType = _queryModelVisitor.QueryCompilationContext.Model .FindEntityType(joinClause.ItemType); if (entityType != null) { return(Visit( EntityQueryModelVisitor.CreatePropertyExpression( expression, entityType.FindPrimaryKey().Properties[0]))); } return(null); } } var type = expression.ReferencedQuerySource.ItemType.UnwrapNullableType().UnwrapEnumType(); if (_relationalTypeMapper.FindMapping(type) != null) { var selectExpression = _queryModelVisitor.TryGetQuery(expression.ReferencedQuerySource); if (selectExpression != null) { var subquery = selectExpression.Tables.FirstOrDefault() as SelectExpression; var innerProjectionExpression = subquery?.Projection.FirstOrDefault() as AliasExpression; if (innerProjectionExpression != null) { if (innerProjectionExpression.Alias != null) { return(new ColumnExpression( innerProjectionExpression.Alias, innerProjectionExpression.Type, subquery)); } var newExpression = selectExpression.UpdateColumnExpression(innerProjectionExpression.Expression, subquery); return(new AliasExpression(newExpression) { SourceMember = innerProjectionExpression.SourceMember }); } } } return(null); }
private static Expression CreateKeyAccessExpression(Expression target, IReadOnlyList <IProperty> properties) { return(properties.Count == 1 ? EntityQueryModelVisitor.CreatePropertyExpression(target, properties[0]) : Expression.New( CompositeKey.CompositeKeyCtor, Expression.NewArrayInit( typeof(object), properties .Select(p => Expression.Convert(EntityQueryModelVisitor.CreatePropertyExpression(target, p), typeof(object))) .Cast <Expression>() .ToArray()))); }
private static Expression CreateKeyAccessExpression(Expression target, IReadOnlyList <IProperty> properties, bool nullComparison) { // If comparing with null then we need only first PK property return((properties.Count == 1) || nullComparison ? EntityQueryModelVisitor.CreatePropertyExpression(target, properties[0]) : Expression.New( CompositeKey.CompositeKeyCtor, Expression.NewArrayInit( typeof(object), properties .Select(p => Expression.Convert(EntityQueryModelVisitor.CreatePropertyExpression(target, p), typeof(object))) .Cast <Expression>() .ToArray()))); }