示例#1
0
        protected virtual Expression ApplyInclude(Expression source, IncludeExpression include, ResourceContext resourceContext)
        {
            using var lambdaScope = _lambdaScopeFactory.CreateScope(_elementType);

            var builder = new IncludeClauseBuilder(source, lambdaScope, resourceContext, _resourceContextProvider);

            return(builder.ApplyInclude(include));
        }
        private IncludeExpression RewriteIncludeForSecondaryEndpoint(IncludeExpression relativeInclude, RelationshipAttribute secondaryRelationship)
        {
            var parentElement = relativeInclude != null
                ? new IncludeElementExpression(secondaryRelationship, relativeInclude.Elements)
                : new IncludeElementExpression(secondaryRelationship);

            return(new IncludeExpression(new[] { parentElement }));
        }
        protected override Expression VisitIncludeStatementExpresson(IncludeExpression expression)
        {
            this.Write("#import \"");
            this.Write(expression.FileName);
            this.WriteLine("\"");

            return(expression);
        }
示例#4
0
        public override IQueryState Accept(IncludeExpression exp)
        {
            ComplexObjectModel owner = (ComplexObjectModel)this.QueryModel.ResultModel;

            owner.Include(exp.NavigationNode, this.QueryModel, false);

            return(this);
        }
示例#5
0
 public virtual void VisitIncludeClause(IncludeExpression <TContext> expression, QueryModel queryModel)
 {
     if (_args != null && _spView != null)
     {
         var visitor = new IncludeExpressionVisitor <TContext>(_args);
         visitor.Visit(expression);
         _spView.ViewFields = visitor.ViewFields;
     }
 }
        public Expression ApplyInclude(IncludeExpression include)
        {
            if (include == null)
            {
                throw new ArgumentNullException(nameof(include));
            }

            return(Visit(include, null));
        }
        public IActionResult Index()
        {
            var anyExample     = new AnyExpression().GetExampleQuery(_context);
            var includeExample = new IncludeExpression().GetExampleQuery(_context);
            var andOrExample   = new AndOrExpression().GetExampleQuery(_context);

            var result = new ExpressionResult(anyExample.ToList(), includeExample.ToList(), andOrExample.ToList());

            return(View(result));
        }
        public override Expression VisitInclude(IncludeExpression expression, object argument)
        {
            Expression source = ApplyEagerLoads(_source, _resourceContext.EagerLoads, null);

            foreach (ResourceFieldChainExpression chain in IncludeChainConverter.GetRelationshipChains(expression))
            {
                source = ProcessRelationshipChain(chain, source);
            }

            return(source);
        }
示例#9
0
        public IIncludableQuery <TEntity, TNavigation> AndWhere(Expression <Func <TNavigation, bool> > predicate)
        {
            IncludeExpression prevIncludeExpression = this.QueryExpression as IncludeExpression;
            NavigationNode    startNavigation       = prevIncludeExpression.NavigationNode.Clone();
            NavigationNode    lastNavigation        = startNavigation.GetLast();

            lastNavigation.Condition = lastNavigation.Condition.And(predicate);

            IncludeExpression includeExpression = new IncludeExpression(typeof(TEntity), prevIncludeExpression.PrevExpression, startNavigation);

            return(new IncludableQuery <TEntity, TNavigation>(this.DbContext, this.TrackEntity, includeExpression));
        }
        /// <inheritdoc />
        public virtual void Read(string parameterName, StringValues parameterValue)
        {
            _lastParameterName = parameterName;

            try
            {
                _includeExpression = GetInclude(parameterValue);
            }
            catch (QueryParseException exception)
            {
                throw new InvalidQueryStringParameterException(parameterName, "The specified include is invalid.", exception.Message, exception);
            }
        }
示例#11
0
 public static IQueryable <TEntity> Include <TEntity>(
     this IQueryable <TEntity> source, params Expression <Func <TEntity, object> >[] predicates)
     where TEntity : class, IListItemEntity, new()
 {
     Check.NotNull(source, nameof(source));
     Check.NotNull(predicates, nameof(predicates));
     if (source.Provider is IQueryProvider)
     {
         var expression = new IncludeExpression <ISpEntryDataContext>(source.Expression, predicates);
         return(new SpEntityQueryable <TEntity>(source.Provider, expression).Concat(new SpEntityQueryable <TEntity>(source.Provider, source.Expression)));
     }
     return(source);
 }
        public IncludeExpression Parse(string source, ResourceContext resourceContextInScope, int?maximumDepth)
        {
            ArgumentGuard.NotNull(resourceContextInScope, nameof(resourceContextInScope));

            _resourceContextInScope = resourceContextInScope;

            Tokenize(source);

            IncludeExpression expression = ParseInclude(maximumDepth);

            AssertTokenStackIsEmpty();

            return(expression);
        }
示例#13
0
        protected IEnumerable <IQueryConstraintProvider> Wrap(IncludeExpression includeExpression)
        {
            var expressionsInScope = new List <ExpressionInScope>
            {
                new ExpressionInScope(null, includeExpression)
            };

            var mock = new Mock <IQueryConstraintProvider>();

            mock.Setup(provider => provider.GetConstraints()).Returns(expressionsInScope);

            IQueryConstraintProvider includeConstraintProvider = mock.Object;

            return(includeConstraintProvider.AsEnumerable());
        }
示例#14
0
        private IEvaluatedIncludeCache GetEvaluatedIncludeCache(IEnumerable <IEnumerable <RelationshipAttribute> > inclusionChains = null)
        {
            if (inclusionChains == null)
            {
                return(new EvaluatedIncludeCache());
            }

            List <ResourceFieldChainExpression> chains = inclusionChains.Select(relationships => new ResourceFieldChainExpression(relationships.ToArray()))
                                                         .ToList();

            IncludeExpression includeExpression = IncludeChainConverter.FromRelationshipChains(chains);

            var evaluatedIncludeCache = new EvaluatedIncludeCache();

            evaluatedIncludeCache.Set(includeExpression);
            return(evaluatedIncludeCache);
        }
示例#15
0
        /// <summary>
        /// Inspects the included relationship chains and selects the ones that starts with the specified relationship.
        /// </summary>
        private IReadOnlyCollection <IReadOnlyCollection <RelationshipAttribute> > GetInclusionChainsStartingWith(RelationshipAttribute relationship)
        {
            IncludeExpression include = _evaluatedIncludeCache.Get() ?? IncludeExpression.Empty;
            IReadOnlyCollection <ResourceFieldChainExpression> chains = IncludeChainConverter.GetRelationshipChains(include);

            var inclusionChains = new List <IReadOnlyCollection <RelationshipAttribute> >();

            foreach (ResourceFieldChainExpression chain in chains)
            {
                if (chain.Fields.First().Equals(relationship))
                {
                    inclusionChains.Add(chain.Fields.Cast <RelationshipAttribute>().ToArray());
                }
            }

            return(inclusionChains);
        }
        public void GivenAnExpressionWithIncludes_WhenVisitedByRemoveIncludesRewriter_IncludesAreRemoved()
        {
            IncludeExpression includeExpression = Expression.Include("a", new SearchParameterInfo("p", "Token"), "Patient", false);
            BinaryExpression  fieldExpression   = Expression.Equals(FieldName.Number, null, 1);

            Assert.Null(includeExpression.AcceptVisitor(RemoveIncludesRewriter.Instance));
            Assert.Null(Expression.And(includeExpression, includeExpression).AcceptVisitor(RemoveIncludesRewriter.Instance));

            Assert.Same(fieldExpression, fieldExpression.AcceptVisitor(RemoveIncludesRewriter.Instance));
            var andWithoutIncludes = Expression.And(fieldExpression, fieldExpression);

            Assert.Same(andWithoutIncludes, andWithoutIncludes.AcceptVisitor(RemoveIncludesRewriter.Instance));

            Assert.Same(fieldExpression, Expression.And(includeExpression, fieldExpression).AcceptVisitor(RemoveIncludesRewriter.Instance));
            Assert.Same(fieldExpression, Expression.And(fieldExpression, includeExpression).AcceptVisitor(RemoveIncludesRewriter.Instance));

            Assert.Equal(andWithoutIncludes.ToString(), Expression.And(includeExpression, fieldExpression, fieldExpression).AcceptVisitor(RemoveIncludesRewriter.Instance).ToString());
            Assert.Equal(andWithoutIncludes.ToString(), Expression.And(fieldExpression, includeExpression, fieldExpression).AcceptVisitor(RemoveIncludesRewriter.Instance).ToString());
            Assert.Equal(andWithoutIncludes.ToString(), Expression.And(fieldExpression, fieldExpression, includeExpression).AcceptVisitor(RemoveIncludesRewriter.Instance).ToString());
        }
示例#17
0
        private IncludeExpression ComposeChildren(QueryLayer topLayer, ICollection <ExpressionInScope> constraints)
        {
            // @formatter:wrap_chained_method_calls chop_always
            // @formatter:keep_existing_linebreaks true

            IncludeExpression include = constraints
                                        .Where(constraint => constraint.Scope == null)
                                        .Select(constraint => constraint.Expression)
                                        .OfType <IncludeExpression>()
                                        .FirstOrDefault() ?? IncludeExpression.Empty;

            // @formatter:keep_existing_linebreaks restore
            // @formatter:wrap_chained_method_calls restore

            IReadOnlyCollection <IncludeElementExpression> includeElements =
                ProcessIncludeSet(include.Elements, topLayer, new List <RelationshipAttribute>(), constraints);

            return(!ReferenceEquals(includeElements, include.Elements)
                ? includeElements.Any() ? new IncludeExpression(includeElements) : IncludeExpression.Empty
                : include);
        }
        public override Expression VisitInclude(IncludeExpression expression, object argument)
        {
            var source = ApplyEagerLoads(_source, _resourceContext.EagerLoads, null);

            foreach (ResourceFieldChainExpression chain in IncludeChainConverter.GetRelationshipChains(expression))
            {
                string path = null;

                foreach (var relationship in chain.Fields.Cast <RelationshipAttribute>())
                {
                    path = path == null ? relationship.RelationshipPath : path + "." + relationship.RelationshipPath;

                    var resourceContext = _resourceContextProvider.GetResourceContext(relationship.RightType);
                    source = ApplyEagerLoads(source, resourceContext.EagerLoads, path);
                }

                source = IncludeExtensionMethodCall(source, path);
            }

            return(source);
        }
        private IEnumerable <IQueryConstraintProvider> GetIncludeConstraints(IEnumerable <IEnumerable <RelationshipAttribute> > inclusionChains = null)
        {
            var expressionsInScope = new List <ExpressionInScope>();

            if (inclusionChains != null)
            {
                List <ResourceFieldChainExpression> chains = inclusionChains.Select(relationships => new ResourceFieldChainExpression(relationships.ToArray()))
                                                             .ToList();

                IncludeExpression includeExpression = IncludeChainConverter.FromRelationshipChains(chains);
                expressionsInScope.Add(new ExpressionInScope(null, includeExpression));
            }

            var mock = new Mock <IQueryConstraintProvider>();

            mock.Setup(provider => provider.GetConstraints()).Returns(expressionsInScope);

            IQueryConstraintProvider includeConstraintProvider = mock.Object;

            return(includeConstraintProvider.AsEnumerable());
        }
示例#20
0
        IncludeExpression BuildThenIncludeExpression(LambdaExpression navigationPath)
        {
            IncludeExpression prevIncludeExpression = this.QueryExpression as IncludeExpression;
            NavigationNode    startNavigation       = prevIncludeExpression.NavigationNode.Clone();
            NavigationNode    lastNavigation        = startNavigation.GetLast();

            List <MemberExpression> memberExps = ExtractMemberAccessChain(navigationPath);

            for (int i = 0; i < memberExps.Count; i++)
            {
                PropertyInfo   member     = memberExps[i].Member as PropertyInfo;
                NavigationNode navigation = InitNavigationNode(member, this.DbContext);

                lastNavigation.Next = navigation;
                lastNavigation      = navigation;
            }

            IncludeExpression includeExpression = new IncludeExpression(typeof(TEntity), prevIncludeExpression.PrevExpression, startNavigation);

            return(includeExpression);
        }
示例#21
0
        public static IFetchSpecification <T> Include <T, TProperty>(
            this IFetchSpecification <T> specification,
            Expression <Func <T, TProperty> > keySelector)
        {
            var includes = new List <IIncludeExpression <T> >();

            if (specification.Include.Any())
            {
                includes.AddRange(specification.Include);
            }
            var includeExpr = new IncludeExpression <T>();

            includeExpr.Include <T, TProperty>(keySelector);
            includes.Add(includeExpr);
            return(new FetchSpecification <T>
                   (
                       include: includes,
                       orderBy: specification.OrderBy,
                       takePage: specification.TakePage
                   ));
        }
示例#22
0
        public IIncludableQuery <TEntity, TCollectionItem> ThenIncludeMany <TCollectionItem>(Expression <Func <TNavigation, IEnumerable <TCollectionItem> > > navigationPath)
        {
            IncludeExpression includeExpression = this.BuildThenIncludeExpression(navigationPath);

            return(new IncludableQuery <TEntity, TCollectionItem>(this.DbContext, this.TrackEntity, includeExpression));
        }
        public override Expression Visit(Expression node)
        {
            switch (node)
            {
            case MethodCallExpression call
                when IsIncludeOrThenIncludeMethod(call.Method):
            {
                var currentSet = new List <List <MemberInfo> > {
                    new List <MemberInfo>()
                };
                var paths = new List <List <MemberInfo> >();
                var inner = call.Arguments[0];
                var type  = inner.Type.GetSequenceType();

                do
                {
                    switch (call.Arguments[1].UnwrapLambda() ?? call.Arguments[1])
                    {
                    case LambdaExpression lambdaExpression:
                    {
                        foreach (var path in currentSet)
                        {
                            path.InsertRange(0, ProcessIncludeLambda(lambdaExpression));
                        }

                        break;
                    }

                    case ConstantExpression constantExpression:
                    {
                        var argument      = (string)((ConstantExpression)call.Arguments[1]).Value;
                        var names         = argument.Split('.').Select(p => p.Trim()).ToArray();
                        var startCount    = currentSet.Count;
                        var resolvedPaths = ResolveIncludePaths(type, names);

                        for (var i = 0; i < startCount; i++)
                        {
                            foreach (var resolvedPath in resolvedPaths)
                            {
                                currentSet.Add(resolvedPath.Concat(currentSet[i]).ToList());
                            }
                        }

                        currentSet.RemoveRange(0, startCount);

                        break;
                    }

                    default:
                    {
                        throw new NotSupportedException($"Include argument expression of type {call.Arguments[1].NodeType} not supported");
                    }
                    }

                    if (IsIncludeOrThenIncludeMethod(call.Method) && !IsThenIncludeMethod(call.Method))
                    {
                        // Paths are inserted at the beginning to preserve the
                        // semantic order of includes defined by the query.
                        paths.InsertRange(0, currentSet);
                        currentSet = new List <List <MemberInfo> > {
                            new List <MemberInfo>()
                        };
                    }

                    inner = call.Arguments[0];
                    type  = inner.Type.GetSequenceType();
                    call  = inner as MethodCallExpression;
                }while (IsIncludeOrThenIncludeMethod(call?.Method));

                if (currentSet.Any(p => p.Any()))
                {
                    paths.InsertRange(0, currentSet);
                }

                var innerSequenceType = inner.Type.GetSequenceType();

                var entityType
                    = model.GetEntityTypes()
                      .Where(t => !t.IsOwned())
                      .FirstOrDefault(t => t.ClrType == innerSequenceType);

                if (entityType == null)
                {
                    throw new NotSupportedException(
                              CoreStrings.IncludeNotSpecifiedDirectlyOnEntityType(
                                  $"Include(\"{string.Join('.', paths.First().Select(m => m.Name))}\")",
                                  paths.First().First().Name));
                }

                var parameter
                    = Expression.Parameter(
                          innerSequenceType,
                          entityType.Relational().TableName.Substring(0, 1).ToLower());

                var includeAccessors
                    = BuildIncludeAccessors(
                          entityType,
                          parameter,
                          paths.AsEnumerable(),
                          new INavigation[0]).ToArray();

                var includeExpression
                    = new IncludeExpression(
                          parameter,
                          includeAccessors.Select(i => i.expression),
                          includeAccessors.Select(i => i.path));

                return(Expression.Call(
                           queryableSelectMethodInfo.MakeGenericMethod(parameter.Type, parameter.Type),
                           Visit(inner),
                           Expression.Lambda(includeExpression, parameter)));
            }

            default:
            {
                return(base.Visit(node));
            }
            }
        }
        private IEnumerable <(Expression expression, IList <INavigation> path)> BuildIncludeAccessors(
            IEntityType entityType,
            Expression baseExpression,
            IEnumerable <IEnumerable <MemberInfo> > paths,
            IList <INavigation> previousPath)
        {
            foreach (var pathset in paths.Where(p => p.Any()).GroupBy(p => p.First(), p => p.Skip(1)))
            {
                var includedMember = pathset.Key;

                var navigation = entityType.GetNavigations().FirstOrDefault(n => n.GetReadableMemberInfo().Equals(includedMember));

                if (navigation == null)
                {
                    // The navigation may be null in some inheritance scenarios.

                    navigation = (from t in entityType.GetDerivedTypes()
                                  from n in t.GetNavigations()
                                  where n.GetReadableMemberInfo().Equals(includedMember)
                                  select n).FirstOrDefault();

                    if (navigation == null)
                    {
                        // TODO: maybe throw?
                        continue;
                    }
                }

                var currentBaseExpression = baseExpression;

                if (includedMember.DeclaringType.IsSubclassOf(currentBaseExpression.Type))
                {
                    currentBaseExpression = Expression.Convert(currentBaseExpression, includedMember.DeclaringType);
                }

                var includedExpression = Expression.MakeMemberAccess(currentBaseExpression, includedMember) as Expression;

                var currentPath = previousPath.ToList();

                currentPath.Add(navigation);

                if (pathset.Any(p => p.Any()))
                {
                    if (includedMember.GetMemberType().IsSequenceType())
                    {
                        var sequenceType   = includedMember.GetMemberType().GetSequenceType();
                        var innerParameter = Expression.Parameter(sequenceType);

                        var innerIncludes
                            = BuildIncludeAccessors(
                                  navigation.GetTargetType(),
                                  innerParameter,
                                  pathset,
                                  new INavigation[0]).ToArray();

                        var includeExpression
                            = new IncludeExpression(
                                  innerParameter,
                                  innerIncludes.Select(i => i.expression),
                                  innerIncludes.Select(i => i.path));

                        var sequenceExpression
                            = (Expression)Expression.Call(
                                  enumerableSelectMethodInfo.MakeGenericMethod(sequenceType, sequenceType),
                                  includedExpression,
                                  Expression.Lambda(includeExpression, innerParameter));

                        if (includedMember.GetMemberType().IsCollectionType())
                        {
                            sequenceExpression = sequenceExpression.AsCollectionType();
                        }

                        yield return(sequenceExpression, currentPath);
                    }
                    else
                    {
                        var innerIncludes
                            = BuildIncludeAccessors(
                                  navigation.GetTargetType(),
                                  includedExpression,
                                  pathset,
                                  currentPath);

                        yield return(includedExpression, currentPath);

                        foreach (var innerInclude in innerIncludes)
                        {
                            yield return(innerInclude);
                        }
                    }
                }
                else
                {
                    yield return(includedExpression, currentPath);
                }
            }
        }
示例#25
0
 public object VisitInclude(IncludeExpression expression, Context context)
 {
     throw new InvalidOperationException($"Include expression should have been removed before reaching {nameof(ExpressionQueryBuilder)}.");
 }
示例#26
0
 public override Expression VisitInclude(IncludeExpression expression, object context)
 {
     return(null);
 }
        public Expression ApplyInclude(IncludeExpression include)
        {
            ArgumentGuard.NotNull(include, nameof(include));

            return(Visit(include, null));
        }
 public NormalizedSearchParameterQueryGenerator VisitInclude(IncludeExpression expression, object context)
 {
     return(IncludeQueryGenerator.Instance);
 }
示例#29
0
        public override JoinQueryResult Visit(IncludeExpression exp)
        {
            JoinQueryResult ret = this.Visit(exp);

            return(ret);
        }
示例#30
0
        public IIncludableQuery <TEntity, TProperty> ThenInclude <TProperty>(Expression <Func <TNavigation, TProperty> > navigationPath)
        {
            IncludeExpression includeExpression = this.BuildThenIncludeExpression(navigationPath);

            return(new IncludableQuery <TEntity, TProperty>(this.DbContext, this.TrackEntity, includeExpression));
        }