/// <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())));
 }
Esempio n. 3
0
 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())));
 }