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); }
public override IQueryState Accept(IncludeExpression exp) { ComplexObjectModel owner = (ComplexObjectModel)this.QueryModel.ResultModel; owner.Include(exp.NavigationNode, this.QueryModel, false); return(this); }
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); }
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); } }
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); }
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()); }
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); }
/// <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()); }
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()); }
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); }
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 )); }
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); } } }
public object VisitInclude(IncludeExpression expression, Context context) { throw new InvalidOperationException($"Include expression should have been removed before reaching {nameof(ExpressionQueryBuilder)}."); }
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); }
public override JoinQueryResult Visit(IncludeExpression exp) { JoinQueryResult ret = this.Visit(exp); return(ret); }
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)); }