コード例 #1
0
		protected override Expression VisitQuerySourceReferenceExpression(QuerySourceReferenceExpression expression)
		{
			if (_results.AggregatingClauses.Contains(expression.ReferencedQuerySource as GroupJoinClause))
			{
				_groupJoin = expression.ReferencedQuerySource as GroupJoinClause;
			}

			return base.VisitQuerySourceReferenceExpression(expression);
		}
コード例 #2
0
		protected override Expression VisitQuerySourceReferenceExpression(QuerySourceReferenceExpression expression)
		{
			if (expression.ReferencedQuerySource == _groupBy)
			{
				return _groupBy.ElementSelector;
			}

			return base.VisitQuerySourceReferenceExpression(expression);
		}
コード例 #3
0
 protected override Expression VisitQuerySourceReferenceExpression(QuerySourceReferenceExpression expression)
 {
     if (expression.ReferencedQuerySource == _querySource)
     { 
         return _inputParameter; 
     }
     
     return expression;
 }
コード例 #4
0
        protected override Expression VisitQuerySourceReferenceExpression(QuerySourceReferenceExpression expression)
		{
			var fromClauseBase = expression.ReferencedQuerySource as FromClauseBase;

			if (fromClauseBase != null && 
			    fromClauseBase.FromExpression is QuerySourceReferenceExpression &&
			    expression.Type == fromClauseBase.FromExpression.Type)
			{
				return fromClauseBase.FromExpression;
			}

		    return base.VisitQuerySourceReferenceExpression(expression);
		}
コード例 #5
0
 protected override Expression VisitQuerySourceReferenceExpression(QuerySourceReferenceExpression expression)
 {
     if (this.memberNames.Count != 0)
     {
         var memberMapPath = new MemberMapPath(this.mappingStore, expression.ReferencedQuerySource.ItemType, this.memberNames);
         this.memberNames.Clear();
         this.fields[memberMapPath.Key] = 1;
     }
     var method = getObjectMethod.MakeGenericMethod(expression.Type);
     return Expression.Call(
         this.resultObjectMappingParameter,
         method,
         Expression.Constant(expression.ReferencedQuerySource));
 }
コード例 #6
0
		protected override Expression VisitQuerySourceReferenceExpression(QuerySourceReferenceExpression expression)
		{
			if (expression.ReferencedQuerySource == _oldClause)
			{
				return new QuerySourceReferenceExpression(_newClause);
			}

			// TODO - really don't like this drill down approach.  Feels fragile
			var mainFromClause = expression.ReferencedQuerySource as MainFromClause;

			if (mainFromClause != null)
			{
				mainFromClause.FromExpression = VisitExpression(mainFromClause.FromExpression);
			}

			return expression;
		}
コード例 #7
0
		protected override Expression VisitQuerySourceReferenceExpression(QuerySourceReferenceExpression expression)
		{
			var fromClause = (FromClauseBase) expression.ReferencedQuerySource;

			if (fromClause.FromExpression is QuerySourceReferenceExpression)
			{
				var querySourceReference = (QuerySourceReferenceExpression) fromClause.FromExpression;

				if (_groupJoinClauses.Contains(querySourceReference.ReferencedQuerySource as GroupJoinClause))
				{
					if (_inAggregate.FlagIsFalse)
					{
						_nonAggregatingGroupJoins.Add((GroupJoinClause) querySourceReference.ReferencedQuerySource);
					}
					else
					{
						_aggregatingGroupJoins.Add((GroupJoinClause) querySourceReference.ReferencedQuerySource);
					}
				}
			}

			return base.VisitQuerySourceReferenceExpression(expression);
		}
コード例 #8
0
 protected HqlTreeNode VisitQuerySourceReferenceExpression(QuerySourceReferenceExpression expression)
 {
     return _hqlTreeBuilder.Ident(expression.ReferencedQuerySource.ItemName);
 }
コード例 #9
0
        private Expression CreateJoinsForNavigations(
            QuerySourceReferenceExpression outerQuerySourceReferenceExpression,
            IEnumerable <INavigation> navigations)
        {
            var querySourceReferenceExpression = outerQuerySourceReferenceExpression;
            var navigationJoins = _navigationJoins;

            foreach (var navigation in navigations)
            {
                var targetEntityType = navigation.GetTargetType();

                if (navigation.IsCollection())
                {
                    _queryModel.MainFromClause.FromExpression = CreateEntityQueryable(targetEntityType);

                    var innerQuerySourceReferenceExpression
                        = new QuerySourceReferenceExpression(_queryModel.MainFromClause);

                    var leftKeyAccess = CreateKeyAccessExpression(
                        querySourceReferenceExpression,
                        navigation.IsDependentToPrincipal()
                                        ? navigation.ForeignKey.Properties
                                        : navigation.ForeignKey.PrincipalKey.Properties);

                    var rightKeyAccess = CreateKeyAccessExpression(
                        innerQuerySourceReferenceExpression,
                        navigation.IsDependentToPrincipal()
                                        ? navigation.ForeignKey.PrincipalKey.Properties
                                        : navigation.ForeignKey.Properties);

                    _queryModel.BodyClauses.Add(
                        new WhereClause(
                            CreateKeyComparisonExpression(leftKeyAccess, rightKeyAccess)));

                    return(_queryModel.MainFromClause.FromExpression);
                }

                var navigationJoin
                    = navigationJoins
                      .FirstOrDefault(nj =>
                                      nj.QuerySource == querySourceReferenceExpression.ReferencedQuerySource &&
                                      nj.Navigation == navigation);

                if (navigationJoin == null)
                {
                    var joinClause
                        = new JoinClause(
                              $"{querySourceReferenceExpression.ReferencedQuerySource.ItemName}.{navigation.Name}",
                              targetEntityType.ClrType,
                              CreateEntityQueryable(targetEntityType),
                              CreateKeyAccessExpression(
                                  querySourceReferenceExpression,
                                  navigation.IsDependentToPrincipal()
                                    ? navigation.ForeignKey.Properties
                                    : navigation.ForeignKey.PrincipalKey.Properties),
                              Expression.Constant(null));

                    var innerQuerySourceReferenceExpression
                        = new QuerySourceReferenceExpression(joinClause);

                    var innerKeySelector
                        = CreateKeyAccessExpression(
                              innerQuerySourceReferenceExpression,
                              navigation.IsDependentToPrincipal()
                                ? navigation.ForeignKey.PrincipalKey.Properties
                                : navigation.ForeignKey.Properties);

                    if (innerKeySelector.Type != joinClause.OuterKeySelector.Type)
                    {
                        innerKeySelector
                            = Expression.Convert(
                                  innerKeySelector,
                                  joinClause.OuterKeySelector.Type);
                    }

                    joinClause.InnerKeySelector = innerKeySelector;

                    navigationJoins.Add(
                        navigationJoin
                            = new NavigationJoin(
                                  querySourceReferenceExpression.ReferencedQuerySource,
                                  navigation,
                                  joinClause,
                                  innerQuerySourceReferenceExpression));
                }

                querySourceReferenceExpression = navigationJoin.QuerySourceReferenceExpression;
                navigationJoins = navigationJoin.NavigationJoins;
            }

            return(querySourceReferenceExpression);
        }
コード例 #10
0
 protected override Expression VisitQuerySourceReferenceExpression(QuerySourceReferenceExpression expression)
 {
     SqlExpression.AppendFormat("(\"{0}\")", expression.ReferencedQuerySource.ItemName);
     return(expression);
 }
コード例 #11
0
            private void Rewrite(QueryModel collectionQueryModel, INavigation navigation)
            {
                var querySourceReferenceFindingExpressionTreeVisitor
                    = new QuerySourceReferenceFindingExpressionVisitor();

                var whereClause = collectionQueryModel.BodyClauses
                                  .OfType <WhereClause>()
                                  .Single();

                whereClause.TransformExpressions(querySourceReferenceFindingExpressionTreeVisitor.Visit);

                collectionQueryModel.BodyClauses.Remove(whereClause);

                var parentQuerySourceReferenceExpression
                    = querySourceReferenceFindingExpressionTreeVisitor.QuerySourceReferenceExpression;

                var parentQuerySource = parentQuerySourceReferenceExpression.ReferencedQuerySource;

                BuildParentOrderings(
                    _parentQueryModel,
                    navigation,
                    parentQuerySourceReferenceExpression,
                    ParentOrderings);

                var querySourceMapping     = new QuerySourceMapping();
                var clonedParentQueryModel = _parentQueryModel.Clone(querySourceMapping);

                _queryCompilationContext.UpdateMapping(querySourceMapping);

                _queryCompilationContext.CloneAnnotations(querySourceMapping, clonedParentQueryModel);

                var clonedParentQuerySourceReferenceExpression
                    = (QuerySourceReferenceExpression)querySourceMapping.GetExpression(parentQuerySource);

                var clonedParentQuerySource
                    = clonedParentQuerySourceReferenceExpression.ReferencedQuerySource;

                AdjustPredicate(
                    clonedParentQueryModel,
                    clonedParentQuerySource,
                    clonedParentQuerySourceReferenceExpression);

                clonedParentQueryModel.SelectClause
                    = new SelectClause(Expression.Default(typeof(AnonymousObject)));

                var subQueryProjection = new List <Expression>();

                var lastResultOperator = ProcessResultOperators(clonedParentQueryModel);

                clonedParentQueryModel.ResultTypeOverride
                    = typeof(IQueryable <>).MakeGenericType(clonedParentQueryModel.SelectClause.Selector.Type);

                var parentItemName
                    = parentQuerySource.HasGeneratedItemName()
                        ? navigation.DeclaringEntityType.DisplayName()[0].ToString().ToLowerInvariant()
                        : parentQuerySource.ItemName;

                collectionQueryModel.MainFromClause.ItemName = $"{parentItemName}.{navigation.Name}";

                var collectionQuerySourceReferenceExpression
                    = new QuerySourceReferenceExpression(collectionQueryModel.MainFromClause);

                var joinQuerySourceReferenceExpression
                    = CreateJoinToParentQuery(
                          clonedParentQueryModel,
                          clonedParentQuerySourceReferenceExpression,
                          collectionQuerySourceReferenceExpression,
                          navigation.ForeignKey,
                          collectionQueryModel,
                          subQueryProjection);

                ApplyParentOrderings(
                    ParentOrderings,
                    clonedParentQueryModel,
                    querySourceMapping,
                    lastResultOperator);

                LiftOrderBy(
                    clonedParentQuerySource,
                    joinQuerySourceReferenceExpression,
                    clonedParentQueryModel,
                    collectionQueryModel,
                    subQueryProjection);

                clonedParentQueryModel.SelectClause.Selector
                    = Expression.New(
                          AnonymousObject.AnonymousObjectCtor,
                          Expression.NewArrayInit(
                              typeof(object),
                              subQueryProjection));
            }
コード例 #12
0
 private static bool IsCollectionNavigation(QuerySourceReferenceExpression qsre, IList <IPropertyBase> properties)
 => qsre != null &&
 properties.Count > 0 &&
 properties[properties.Count - 1] is INavigation navigation &&
コード例 #13
0
 protected override Expression VisitQuerySourceReferenceExpression(QuerySourceReferenceExpression expression)
 {
     return(_parameter);
 }
コード例 #14
0
                protected override Expression VisitQuerySourceReference(QuerySourceReferenceExpression querySourceReferenceExpression)
                {
                    QuerySources.Add(querySourceReferenceExpression.TryGetReferencedQuerySource());

                    return(base.VisitQuerySourceReference(querySourceReferenceExpression));
                }
コード例 #15
0
 protected override Expression VisitQuerySourceReference(QuerySourceReferenceExpression expression)
 {
     return(AddAndConvertExpression(expression));
 }
コード例 #16
0
 protected override Expression VisitQuerySourceReferenceExpression(QuerySourceReferenceExpression expression)
 {
     // If the (sub)expression contains a QuerySourceReference, then the entire expression should be nominated
     _requiresRootNomination = true;
     return(base.VisitQuerySourceReferenceExpression(expression));
 }
コード例 #17
0
 protected override MemberExpression Rewrite(QuerySourceReferenceExpression expression)
 {
     return(Expression.MakeMemberAccess(expression, OuterExpr.Member));
 }
コード例 #18
0
 protected abstract T Rewrite(QuerySourceReferenceExpression expression);
コード例 #19
0
        /// <summary>Visits a query source expression.</summary>
        /// <param name="expression">Expression to be visited.</param>
        /// <returns>Expression visited.</returns>
        protected override System.Linq.Expressions.Expression VisitQuerySourceReference(QuerySourceReferenceExpression expression)
        {
            Remotion.Linq.Clauses.FromClauseBase sourceExpression = GetSourceExpression(expression);
            StrongEntityAccessor entityAccessor = this.GetEntityAccessor(sourceExpression);

            if (entityAccessor != null)
            {
                _query.AddEntityAccessor(entityAccessor);
                _lastComponent = _query;
            }
            else
            {
                _lastComponent = (from entityConstrain in _query.FindAllComponents <EntityConstrain>()
                                  where entityConstrain.GetType() == typeof(EntityConstrain)
                                  let identifier = entityConstrain.Value as Identifier
                                                   let targetExpression = ((IQueryVisitor)this).TransformFromExpression(sourceExpression).FromExpression
                                                                          where (identifier != null) && (targetExpression != null) && (entityConstrain.TargetExpression.EqualsTo(targetExpression))
                                                                          select identifier).FirstOrDefault();
                HandleComponent(_lastComponent);
            }

            return(expression);
        }
コード例 #20
0
 protected override Expression VisitQuerySourceReferenceExpression(QuerySourceReferenceExpression expression)
 {
     ArgumentUtility.CheckNotNull("expression", expression);
     return(Expression.Parameter(expression.Type, "[" + expression.ReferencedQuerySource.ItemName + "]"));
 }
コード例 #21
0
		protected override Expression VisitQuerySourceReferenceExpression(QuerySourceReferenceExpression expression)
		{
			_source = expression;
			return expression;
		}
コード例 #22
0
        /// <summary>
        /// 解析 QuerySourceReference 表达式
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        protected override Expression VisitQuerySourceReferenceExpression(QuerySourceReferenceExpression expression)
        {
            this.commandBuilder.WherePartsBuilder.Append(string.Format("{0}.", expression.ReferencedQuerySource.ItemName.ToLower()));

            return(expression);
        }
コード例 #23
0
 protected override Expression VisitQuerySourceReference(QuerySourceReferenceExpression expression)
 {
     _querySource = expression.ReferencedQuerySource;
     return(base.VisitQuerySourceReference(expression));
 }
コード例 #24
0
        protected override Expression VisitQuerySourceReference(QuerySourceReferenceExpression expression)
        {
            _expression.Append(_queryGenerationContext.ExtentNameProvider.GetExtentName(expression.ReferencedQuerySource));

            return(expression);
        }
コード例 #25
0
 /// <inheritdoc />
 protected override Expression VisitQuerySourceReference(QuerySourceReferenceExpression expression)
 {
     LogWriter.WriteLine($"VisitQuerySourceReference: {expression}");
     return(expression);
 }
コード例 #26
0
 protected virtual Expression VisitQuerySourceReferenceExpression(QuerySourceReferenceExpression expression)
 {
     return(expression);
 }
 protected override Expression VisitQuerySourceReferenceExpression(QuerySourceReferenceExpression expression)
 {
     luceneExpression.AttachIndex(expression.ReferencedQuerySource.ItemType.GetContractId());
     luceneExpression.Append(expression.ReferencedQuerySource.ItemName);
     return(expression);
 }
コード例 #28
0
            private static void LiftOrderBy(
                IQuerySource querySource,
                Expression targetExpression,
                QueryModel fromQueryModel,
                QueryModel toQueryModel,
                List <Expression> subQueryProjection)
            {
                var canRemove
                    = !fromQueryModel.ResultOperators
                      .Any(r => r is SkipResultOperator || r is TakeResultOperator);

                foreach (var orderByClause
                         in fromQueryModel.BodyClauses.OfType <OrderByClause>().ToArray())
                {
                    var outerOrderByClause = new OrderByClause();

                    foreach (var ordering in orderByClause.Orderings)
                    {
                        int projectionIndex;
                        var orderingExpression = ordering.Expression;
                        if (ordering.Expression.RemoveConvert() is NullConditionalExpression nullConditionalExpression)
                        {
                            orderingExpression = nullConditionalExpression.AccessOperation;
                        }

                        QuerySourceReferenceExpression orderingExpressionQsre = null;
                        string orderingExpressionName = null;
                        if (orderingExpression.RemoveConvert() is MemberExpression memberExpression &&
                            memberExpression.Expression.RemoveConvert() is QuerySourceReferenceExpression memberQsre &&
                            memberQsre.ReferencedQuerySource == querySource)
                        {
                            orderingExpressionQsre = memberQsre;
                            orderingExpressionName = memberExpression.Member.Name;
                        }

                        if (orderingExpression.RemoveConvert() is MethodCallExpression methodCallExpression &&
                            methodCallExpression.IsEFProperty() &&
                            methodCallExpression.Arguments[0].RemoveConvert() is QuerySourceReferenceExpression methodCallQsre &&
                            methodCallQsre.ReferencedQuerySource == querySource)
                        {
                            orderingExpressionQsre = methodCallQsre;
                            orderingExpressionName = (string)((ConstantExpression)methodCallExpression.Arguments[1]).Value;
                        }

                        if (orderingExpressionQsre != null && orderingExpressionName != null)
                        {
                            projectionIndex
                                = subQueryProjection
                                  .FindIndex(
                                      e =>
                            {
                                var expressionWithoutConvert = e.RemoveConvert();
                                var projectionExpression     = (expressionWithoutConvert as NullConditionalExpression)?.AccessOperation
                                                               ?? expressionWithoutConvert;

                                if (projectionExpression is MethodCallExpression methodCall &&
                                    methodCall.Method.IsEFPropertyMethod())
                                {
                                    var properyQsre  = (QuerySourceReferenceExpression)methodCall.Arguments[0].RemoveConvert();
                                    var propertyName = (string)((ConstantExpression)methodCall.Arguments[1]).Value;

                                    return(properyQsre.ReferencedQuerySource == orderingExpressionQsre.ReferencedQuerySource &&
                                           propertyName == orderingExpressionName);
                                }

                                if (projectionExpression is MemberExpression projectionMemberExpression)
                                {
                                    var projectionMemberQsre = (QuerySourceReferenceExpression)projectionMemberExpression.Expression.RemoveConvert();

                                    return(projectionMemberQsre.ReferencedQuerySource == orderingExpressionQsre.ReferencedQuerySource &&
                                           projectionMemberExpression.Member.Name == orderingExpressionName);
                                }

                                return(false);
                            });
                        }
                        else
                        {
                            projectionIndex
                                = subQueryProjection
                                  // Do NOT use orderingExpression variable here
                                  .FindIndex(e => ExpressionEqualityComparer.Instance.Equals(e.RemoveConvert(), ordering.Expression.RemoveConvert()));
                        }

                        if (projectionIndex == -1)
                        {
                            projectionIndex = subQueryProjection.Count;

                            subQueryProjection.Add(
                                Expression.Convert(
                                    // Workaround re-linq#RMLNQ-111 - When this is fixed the Clone can go away
                                    CloningExpressionVisitor.AdjustExpressionAfterCloning(
                                        ordering.Expression,
                                        new QuerySourceMapping()),
                                    typeof(object)));
                        }

                        var newExpression
                            = Expression.Call(
                                  targetExpression,
                                  AnonymousObject.GetValueMethodInfo,
                                  Expression.Constant(projectionIndex));

                        outerOrderByClause.Orderings
                        .Add(new Ordering(newExpression, ordering.OrderingDirection));
                    }

                    toQueryModel.BodyClauses.Add(outerOrderByClause);

                    if (canRemove)
                    {
                        fromQueryModel.BodyClauses.Remove(orderByClause);
                    }
                }
            }
コード例 #29
0
 protected override Expression VisitQuerySourceReferenceExpression(QuerySourceReferenceExpression expression)
 {
     CompletePath();
     return(BaseVisitQuerySourceReferenceExpression(expression));
 }
コード例 #30
0
 protected override Expression VisitQuerySourceReference(QuerySourceReferenceExpression expression)
 {
     return(expression);
 }
        private Expression Rewrite(
            int correlatedCollectionIndex,
            QueryModel collectionQueryModel,
            INavigation navigation,
            bool trackingQuery,
            QuerySourceReferenceExpression originQuerySource,
            bool forceListResult,
            Type listResultElementType)
        {
            var querySourceReferenceFindingExpressionTreeVisitor
                = new QuerySourceReferenceFindingExpressionVisitor();

            var originalCorrelationPredicate = collectionQueryModel.BodyClauses.OfType <WhereClause>()
                                               .Single(c => c.Predicate is NullSafeEqualExpression);

            collectionQueryModel.BodyClauses.Remove(originalCorrelationPredicate);

            var keyEquality = ((NullSafeEqualExpression)originalCorrelationPredicate.Predicate).EqualExpression;

            querySourceReferenceFindingExpressionTreeVisitor.Visit(keyEquality.Left);
            var parentQuerySourceReferenceExpression = querySourceReferenceFindingExpressionTreeVisitor.QuerySourceReferenceExpression;

            querySourceReferenceFindingExpressionTreeVisitor = new QuerySourceReferenceFindingExpressionVisitor();
            querySourceReferenceFindingExpressionTreeVisitor.Visit(keyEquality.Right);

            var currentKey = BuildKeyAccess(navigation.ForeignKey.Properties, querySourceReferenceFindingExpressionTreeVisitor.QuerySourceReferenceExpression);

            // PK of the parent qsre
            var originKey = BuildKeyAccess(_queryCompilationContext.Model.FindEntityType(originQuerySource.Type).FindPrimaryKey().Properties, originQuerySource);

            // principal side of the FK relationship between parent and this collection
            var outerKey = BuildKeyAccess(navigation.ForeignKey.PrincipalKey.Properties, parentQuerySourceReferenceExpression);

            var parentQuerySource = parentQuerySourceReferenceExpression.ReferencedQuerySource;

            // ordering priority for parent:
            // - user specified orderings
            // - parent PK
            // - principal side of the FK between parent and child

            // ordering priority for child:
            // - user specified orderings on parent (from join)
            // - parent PK (from join)
            // - dependent side of the FK between parent and child
            // - customer specified orderings on child

            var parentOrderings = new List <Ordering>();

            foreach (var existingParentOrderByClause in _parentQueryModel.BodyClauses.OfType <OrderByClause>())
            {
                parentOrderings.AddRange(existingParentOrderByClause.Orderings);
            }

            var originEntityType = _queryCompilationContext.Model.FindEntityType(originQuerySource.Type);

            foreach (var property in originEntityType.FindPrimaryKey().Properties)
            {
                TryAddPropertyToOrderings(property, originQuerySource, parentOrderings);
            }

            foreach (var property in navigation.ForeignKey.PrincipalKey.Properties)
            {
                TryAddPropertyToOrderings(property, parentQuerySourceReferenceExpression, parentOrderings);
            }

            _parentOrderings.AddRange(parentOrderings);

            // if selector contains multiple correlated collections, visiting the first one changes that collections QM (changing it's type)
            // which makes the parent QM inconsistent temporarily. QM's type is different but the CorrelateCollections method that fixes the result type
            // is not part of the QM and it's added only when the entire Selector is replaced - i.e. after all it's components have been visited

            // since when we clone the parent QM, we don't care about it's original selector anyway (it's being discarded)
            // we avoid cloning the selector in the first place and avoid all the potential problem with temporarily mismatched types of the subqueries inside
            var parentSelectClause = _parentQueryModel.SelectClause;

            _parentQueryModel.SelectClause = new SelectClause(Expression.Default(parentSelectClause.Selector.Type));

            var querySourceMapping     = new QuerySourceMapping();
            var clonedParentQueryModel = _parentQueryModel.Clone(querySourceMapping);

            _parentQueryModel.SelectClause = parentSelectClause;

            _queryCompilationContext.UpdateMapping(querySourceMapping);
            _queryCompilationContext.CloneAnnotations(querySourceMapping, clonedParentQueryModel);

            var clonedParentQuerySourceReferenceExpression
                = (QuerySourceReferenceExpression)querySourceMapping.GetExpression(parentQuerySource);

            var parentItemName
                = parentQuerySource.HasGeneratedItemName()
                    ? navigation.DeclaringEntityType.ShortName()[0].ToString().ToLowerInvariant()
                    : parentQuerySource.ItemName;

            collectionQueryModel.MainFromClause.ItemName = $"{parentItemName}.{navigation.Name}";

            var collectionQuerySourceReferenceExpression
                = new QuerySourceReferenceExpression(collectionQueryModel.MainFromClause);

            var subQueryProjection           = new List <Expression>();
            var orderingsToProjectionMapping = new List <int>();

            foreach (var existingClonedOrderByClause in clonedParentQueryModel.BodyClauses.OfType <OrderByClause>())
            {
                foreach (var existingClonedOrdering in existingClonedOrderByClause.Orderings)
                {
                    var matchingIndex = subQueryProjection
                                        .Select(
                        (o, i) => new
                    {
                        o,
                        i
                    })
                                        .Where(
                        e => ExpressionEqualityComparer.Instance.Equals(e.o, existingClonedOrdering.Expression) ||
                        AreEquivalentPropertyExpressions(e.o, existingClonedOrdering.Expression)).Select(e => (int?)e.i).FirstOrDefault();

                    if (matchingIndex == null)
                    {
                        orderingsToProjectionMapping.Add(subQueryProjection.Count);
                        subQueryProjection.Add(existingClonedOrdering.Expression);
                    }
                    else
                    {
                        orderingsToProjectionMapping.Add(matchingIndex.Value);
                    }
                }
            }

            var index = subQueryProjection.Count;

            foreach (var parentOrdering in parentOrderings.Skip(orderingsToProjectionMapping.Count))
            {
                orderingsToProjectionMapping.Add(index++);
                subQueryProjection.Add(CloningExpressionVisitor.AdjustExpressionAfterCloning(parentOrdering.Expression, querySourceMapping));
            }

            var joinQuerySourceReferenceExpression
                = CreateJoinToParentQuery(
                      clonedParentQueryModel,
                      clonedParentQuerySourceReferenceExpression,
                      collectionQuerySourceReferenceExpression,
                      navigation.ForeignKey,
                      collectionQueryModel,
                      subQueryProjection);

            var lastResultOperator = ProcessResultOperators(clonedParentQueryModel);

            var clonedParentOrderings = new List <Ordering>();

            for (var i = 0; i < parentOrderings.Count; i++)
            {
                clonedParentOrderings.Add(new Ordering(subQueryProjection[orderingsToProjectionMapping[i]], parentOrderings[i].OrderingDirection));
            }

            ApplyParentOrderings(
                clonedParentOrderings,
                clonedParentQueryModel,
                querySourceMapping,
                lastResultOperator);

            LiftOrderBy(
                joinQuerySourceReferenceExpression,
                clonedParentQueryModel,
                collectionQueryModel,
                orderingsToProjectionMapping);

            clonedParentQueryModel.SelectClause.Selector
                = Expression.New(
                      MaterializedAnonymousObject.AnonymousObjectCtor,
                      Expression.NewArrayInit(
                          typeof(object),
                          subQueryProjection.Select(e => Expression.Convert(e, typeof(object)))));

            clonedParentQueryModel.ResultTypeOverride = typeof(IQueryable <>).MakeGenericType(clonedParentQueryModel.SelectClause.Selector.Type);

            var newOriginKey = CloningExpressionVisitor
                               .AdjustExpressionAfterCloning(originKey, querySourceMapping);

            var newOriginKeyElements      = ((NewArrayExpression)(((NewExpression)newOriginKey).Arguments[0])).Expressions;
            var remappedOriginKeyElements = RemapOriginKeyExpressions(newOriginKeyElements, joinQuerySourceReferenceExpression, subQueryProjection);

            var collectionQueryModelSelectorType = collectionQueryModel.SelectClause.Selector.Type;

            var tupleCtor = typeof(Tuple <, ,>).MakeGenericType(
                collectionQueryModelSelectorType,
                typeof(MaterializedAnonymousObject),
                typeof(MaterializedAnonymousObject)).GetConstructors().FirstOrDefault();

            var navigationParameter = Expression.Parameter(typeof(INavigation), "n");

            var correlateSubqueryMethod = _queryCompilationContext.IsAsyncQuery
                ? _correlateSubqueryAsyncMethodInfo
                : _correlateSubqueryMethodInfo;

            Expression resultCollectionFactoryExpressionBody;

            if (forceListResult ||
                navigation.ForeignKey.DeclaringEntityType.ClrType != collectionQueryModelSelectorType)
            {
                listResultElementType = listResultElementType ?? collectionQueryModelSelectorType;
                var resultCollectionType = typeof(List <>).MakeGenericType(listResultElementType);
                var resultCollectionCtor = resultCollectionType.GetTypeInfo().GetDeclaredConstructor(Array.Empty <Type>());

                correlateSubqueryMethod = correlateSubqueryMethod.MakeGenericMethod(
                    collectionQueryModelSelectorType,
                    listResultElementType,
                    typeof(List <>).MakeGenericType(listResultElementType));

                resultCollectionFactoryExpressionBody = Expression.New(resultCollectionCtor);

                trackingQuery = false;
            }
            else
            {
                correlateSubqueryMethod = correlateSubqueryMethod.MakeGenericMethod(
                    collectionQueryModelSelectorType,
                    collectionQueryModelSelectorType,
                    navigation.GetCollectionAccessor().CollectionType);

                resultCollectionFactoryExpressionBody
                    = Expression.Convert(
                          Expression.Call(
                              Expression.Call(_getCollectionAccessorMethodInfo, navigationParameter),
                              _createCollectionMethodInfo),
                          navigation.GetCollectionAccessor().CollectionType);
            }

            var resultCollectionFactoryExpression = Expression.Lambda(
                resultCollectionFactoryExpressionBody,
                navigationParameter);

            collectionQueryModel.SelectClause.Selector
                = Expression.New(
                      tupleCtor, collectionQueryModel.SelectClause.Selector, currentKey, Expression.New(
                          MaterializedAnonymousObject.AnonymousObjectCtor,
                          Expression.NewArrayInit(
                              typeof(object),
                              remappedOriginKeyElements)));

            collectionQueryModelSelectorType = collectionQueryModel.SelectClause.Selector.Type;

            // Enumerable or OrderedEnumerable
            collectionQueryModel.ResultTypeOverride = collectionQueryModel.BodyClauses.OfType <OrderByClause>().Any()
                ? typeof(IOrderedEnumerable <>).MakeGenericType(collectionQueryModelSelectorType)
                : typeof(IEnumerable <>).MakeGenericType(collectionQueryModelSelectorType);

            var lambda = (Expression)Expression.Lambda(new SubQueryExpression(collectionQueryModel));

            if (_queryCompilationContext.IsAsyncQuery)
            {
                lambda = Expression.Convert(
                    lambda,
                    typeof(Func <>).MakeGenericType(
                        typeof(IAsyncEnumerable <>).MakeGenericType(collectionQueryModelSelectorType)));
            }

            // since we cloned QM, we need to check if it's query sources require materialization (e.g. TypeIs operation for InMemory)
            _queryCompilationContext.FindQuerySourcesRequiringMaterialization(_queryModelVisitor, collectionQueryModel);

            var correlationPredicate = CreateCorrelationPredicate(navigation);

            var arguments = new List <Expression>
            {
                Expression.Constant(correlatedCollectionIndex),
                Expression.Constant(navigation),
                resultCollectionFactoryExpression,
                outerKey,
                Expression.Constant(trackingQuery),
                lambda,
                correlationPredicate
            };

            if (_queryCompilationContext.IsAsyncQuery)
            {
                arguments.Add(IncludeCompiler.CancellationTokenParameter);
            }

            var result = Expression.Call(
                Expression.Property(
                    EntityQueryModelVisitor.QueryContextParameter,
                    nameof(QueryContext.QueryBuffer)),
                correlateSubqueryMethod,
                arguments);

            if (_queryCompilationContext.IsAsyncQuery)
            {
                return(new TaskBlockingExpressionVisitor().Visit(result));
            }

            return(result);
        }
コード例 #32
0
 protected HqlTreeNode VisitQuerySourceReferenceExpression(QuerySourceReferenceExpression expression)
 {
     return(_hqlTreeBuilder.Ident(_parameters.QuerySourceNamer.GetName(expression.ReferencedQuerySource)));
 }
コード例 #33
0
 protected override Expression VisitQuerySourceReference(QuerySourceReferenceExpression expression)
 {
     _containsNakedQuerySourceReferenceExpression = true;
     return(expression);
 }
コード例 #34
0
		protected override Expression VisitQuerySourceReferenceExpression(QuerySourceReferenceExpression expression)
		{
			if (expression.ReferencedQuerySource == _querySource)
			{
				_references = true;
			}

			return expression;
		}
コード例 #35
0
 protected override Expression VisitQuerySourceReference(QuerySourceReferenceExpression node)
 {
     EmitField(node);
     return(node);
 }
コード例 #36
0
 protected override Expression VisitQuerySourceReferenceExpression(QuerySourceReferenceExpression expression)
 {
     return _parameter;
 }
コード例 #37
0
            protected void Compile(
                QueryCompilationContext queryCompilationContext,
                QueryModel queryModel,
                bool trackingQuery,
                bool asyncQuery,
                ref int collectionIncludeId,
                QuerySourceReferenceExpression targetQuerySourceReferenceExpression)
            {
                var entityParameter
                    = Expression.Parameter(targetQuerySourceReferenceExpression.Type, name: "entity");

                var propertyExpressions = new List <Expression>();
                var blockExpressions    = new List <Expression>();

                if (trackingQuery)
                {
                    blockExpressions.Add(
                        Expression.Call(
                            Expression.Property(
                                EntityQueryModelVisitor.QueryContextParameter,
                                nameof(QueryContext.QueryBuffer)),
                            _queryBufferStartTrackingMethodInfo,
                            entityParameter,
                            Expression.Constant(
                                queryCompilationContext.FindEntityType(targetQuerySourceReferenceExpression.ReferencedQuerySource)
                                ?? queryCompilationContext.Model.FindEntityType(entityParameter.Type))));
                }

                var includedIndex = 0;

                // ReSharper disable once LoopCanBeConvertedToQuery
                foreach (var includeLoadTreeNode in Children)
                {
                    blockExpressions.Add(
                        includeLoadTreeNode.Compile(
                            queryCompilationContext,
                            targetQuerySourceReferenceExpression,
                            entityParameter,
                            propertyExpressions,
                            trackingQuery,
                            asyncQuery,
                            ref includedIndex,
                            ref collectionIncludeId));
                }

                if (blockExpressions.Count > 1 ||
                    blockExpressions.Count == 1 &&
                    !trackingQuery)
                {
                    AwaitTaskExpressions(asyncQuery, blockExpressions);

                    var includeExpression
                        = blockExpressions.Last().Type == typeof(Task)
                            ? (Expression)Expression.Property(
                              Expression.Call(
                                  _includeAsyncMethodInfo
                                  .MakeGenericMethod(targetQuerySourceReferenceExpression.Type),
                                  EntityQueryModelVisitor.QueryContextParameter,
                                  targetQuerySourceReferenceExpression,
                                  Expression.NewArrayInit(typeof(object), propertyExpressions),
                                  Expression.Lambda(
                                      Expression.Block(blockExpressions),
                                      EntityQueryModelVisitor.QueryContextParameter,
                                      entityParameter,
                                      _includedParameter,
                                      _cancellationTokenParameter),
                                  _cancellationTokenParameter),
                              nameof(Task <object> .Result))
                            : Expression.Call(
                              _includeMethodInfo.MakeGenericMethod(targetQuerySourceReferenceExpression.Type),
                              EntityQueryModelVisitor.QueryContextParameter,
                              targetQuerySourceReferenceExpression,
                              Expression.NewArrayInit(typeof(object), propertyExpressions),
                              Expression.Lambda(
                                  Expression.Block(typeof(void), blockExpressions),
                                  EntityQueryModelVisitor.QueryContextParameter,
                                  entityParameter,
                                  _includedParameter));

                    ApplyIncludeExpressionsToQueryModel(
                        queryModel, targetQuerySourceReferenceExpression, includeExpression);
                }
            }
コード例 #38
0
 protected Expression BaseVisitQuerySourceReference(QuerySourceReferenceExpression expression)
 {
     return(base.VisitQuerySourceReference(expression));
 }
コード例 #39
0
        /// <summary>
        /// 解析 QuerySourceReference 表达式
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        protected override Expression VisitQuerySourceReferenceExpression(QuerySourceReferenceExpression expression)
        {
            builder.Append(string.Format("{0}.", expression.ReferencedQuerySource.ItemName.ToUpper()));

            return(expression);
        }
コード例 #40
0
 protected internal override Expression VisitQuerySourceReference(QuerySourceReferenceExpression expression)
 {
     return(VisitUnhandledItem <QuerySourceReferenceExpression, Expression> (expression, "VisitQuerySourceReference", BaseVisitQuerySourceReference));
 }
コード例 #41
0
 protected override Expression VisitQuerySourceReference(QuerySourceReferenceExpression expression)
 {
     _sqlExpression.Append(expression.ReferencedQuerySource.ItemName);
     return(expression);
 }