private IEnumerable <IncludeLoadTree> CreateIncludeLoadTrees(QueryModel queryModel, bool shouldThrow) { var querySourceTracingExpressionVisitor = _querySourceTracingExpressionVisitorFactory.Create(); var includeLoadTrees = new List <IncludeLoadTree>(); foreach (var includeResultOperator in _includeResultOperators.ToArray()) { var querySourceReferenceExpression = querySourceTracingExpressionVisitor .FindResultQuerySourceReferenceExpression( queryModel.GetOutputExpression(), includeResultOperator.QuerySource); if (querySourceReferenceExpression == null) { continue; } if (querySourceReferenceExpression.Type.IsGrouping() && querySourceTracingExpressionVisitor.OriginGroupByQueryModel != null) { querySourceReferenceExpression = querySourceTracingExpressionVisitor .FindResultQuerySourceReferenceExpression( querySourceTracingExpressionVisitor.OriginGroupByQueryModel.GetOutputExpression(), includeResultOperator.QuerySource); _targetQueryModel = querySourceTracingExpressionVisitor.OriginGroupByQueryModel; } if (querySourceReferenceExpression?.Type.IsGrouping() != false) { continue; } var includeLoadTree = includeLoadTrees .SingleOrDefault( t => ReferenceEquals( t.QuerySourceReferenceExpression, querySourceReferenceExpression)); if (includeLoadTree == null) { includeLoadTrees.Add(includeLoadTree = new IncludeLoadTree(querySourceReferenceExpression)); } if (!TryPopulateIncludeLoadTree(includeResultOperator, includeLoadTree, shouldThrow)) { includeLoadTrees.Remove(includeLoadTree); continue; } _queryCompilationContext.Logger.NavigationIncluded(includeResultOperator); _includeResultOperators.Remove(includeResultOperator); } return(includeLoadTrees); }
private static bool WalkNavigations( IEntityType entityType, IReadOnlyList <string> navigationPropertyPaths, IncludeLoadTree includeLoadTree, bool shouldThrow) { var longestMatchFound = WalkNavigationsInternal( entityType, navigationPropertyPaths, includeLoadTree, new Stack <INavigation>(), (0, entityType)); if (longestMatchFound.Depth < navigationPropertyPaths.Count) { if (shouldThrow) { throw new InvalidOperationException( CoreStrings.IncludeBadNavigation( navigationPropertyPaths[longestMatchFound.Depth], longestMatchFound.EntityType.DisplayName())); } return(false); } return(true); }
private bool TryPopulateIncludeLoadTree( IncludeResultOperator includeResultOperator, IncludeLoadTree includeLoadTree, bool shouldThrow) { if (includeResultOperator.NavigationPaths != null) { foreach (var navigationPath in includeResultOperator.NavigationPaths) { includeLoadTree.AddLoadPath(navigationPath); } return(true); } IEntityType entityType = null; if (includeResultOperator.PathFromQuerySource is QuerySourceReferenceExpression qsre) { entityType = _queryCompilationContext.FindEntityType(qsre.ReferencedQuerySource); } if (entityType == null) { entityType = _queryCompilationContext.Model.FindEntityType(includeResultOperator.PathFromQuerySource.Type); if (entityType == null) { var pathFromSource = MemberAccessBindingExpressionVisitor.GetPropertyPath( includeResultOperator.PathFromQuerySource, _queryCompilationContext, out qsre); if (pathFromSource.Count > 0 && pathFromSource[pathFromSource.Count - 1] is INavigation navigation) { entityType = navigation.GetTargetType(); } } } if (entityType == null) { if (shouldThrow) { throw new InvalidOperationException( CoreStrings.IncludeNotSpecifiedDirectlyOnEntityType( includeResultOperator.ToString(), includeResultOperator.NavigationPropertyPaths.FirstOrDefault())); } return(false); } return(WalkNavigations(entityType, includeResultOperator.NavigationPropertyPaths, includeLoadTree, shouldThrow)); }
private IEnumerable <IncludeLoadTree> CreateIncludeLoadTrees( Expression targetExpression) { var querySourceTracingExpressionVisitor = _querySourceTracingExpressionVisitorFactory.Create(); var includeLoadTrees = new List <IncludeLoadTree>(); foreach (var includeResultOperator in _includeResultOperators.ToArray()) { var navigationPath = includeResultOperator.GetNavigationPath(_queryCompilationContext); var querySourceReferenceExpression = querySourceTracingExpressionVisitor .FindResultQuerySourceReferenceExpression( targetExpression, includeResultOperator.QuerySource); if (querySourceReferenceExpression == null) { continue; } var includeLoadTree = includeLoadTrees .SingleOrDefault( t => ReferenceEquals( t.QuerySourceReferenceExpression, querySourceReferenceExpression)); if (includeLoadTree == null) { includeLoadTrees.Add(includeLoadTree = new IncludeLoadTree(querySourceReferenceExpression)); } includeLoadTree.AddLoadPath(navigationPath); _queryCompilationContext.Logger .LogDebug( CoreEventId.IncludingNavigation, () => CoreStrings.LogIncludingNavigation(includeResultOperator.DisplayString())); _includeResultOperators.Remove(includeResultOperator); } return(includeLoadTrees); }
private IEnumerable <IncludeLoadTree> CreateIncludeLoadTrees(QueryModel queryModel) { var querySourceTracingExpressionVisitor = _querySourceTracingExpressionVisitorFactory.Create(); var includeLoadTrees = new List <IncludeLoadTree>(); foreach (var includeResultOperator in _includeResultOperators.ToArray()) { var navigationPath = includeResultOperator.GetNavigationPath(_queryCompilationContext); var querySourceReferenceExpression = querySourceTracingExpressionVisitor .FindResultQuerySourceReferenceExpression( queryModel.GetOutputExpression(), includeResultOperator.QuerySource); if (querySourceReferenceExpression == null || navigationPath == null) { continue; } var includeLoadTree = includeLoadTrees .SingleOrDefault( t => ReferenceEquals( t.QuerySourceReferenceExpression, querySourceReferenceExpression)); if (includeLoadTree == null) { includeLoadTrees.Add(includeLoadTree = new IncludeLoadTree(querySourceReferenceExpression)); } includeLoadTree.AddLoadPath(navigationPath); _queryCompilationContext.Logger.NavigationIncluded(includeResultOperator); _includeResultOperators.Remove(includeResultOperator); } return(includeLoadTrees); }
private static KeyValuePair <int, IEntityType> WalkNavigationsInternal( IEntityType entityType, IReadOnlyList <string> navigationPropertyPaths, IncludeLoadTree includeLoadTree, Stack <INavigation> stack, KeyValuePair <int, IEntityType> longestMatchFound) { var outboundNavigations = entityType.GetNavigations() .Concat(entityType.GetDerivedTypes().SelectMany(et => et.GetDeclaredNavigations())) .Where(n => navigationPropertyPaths.Count > stack.Count && n.Name == navigationPropertyPaths[stack.Count]) .ToList(); if (outboundNavigations.Count == 0 && stack.Count > 0) { includeLoadTree.AddLoadPath(stack.Reverse().ToArray()); if (stack.Count > longestMatchFound.Key) { longestMatchFound = new KeyValuePair <int, IEntityType>(stack.Count, entityType); } } else { foreach (var navigation in outboundNavigations) { stack.Push(navigation); longestMatchFound = WalkNavigationsInternal(navigation.GetTargetType(), navigationPropertyPaths, includeLoadTree, stack, longestMatchFound); stack.Pop(); } } return(longestMatchFound); }
private static (int Depth, IEntityType EntityType) WalkNavigationsInternal( IEntityType entityType, IReadOnlyList <string> navigationPropertyPaths, IncludeLoadTree includeLoadTree, Stack <INavigation> stack, (int Depth, IEntityType EntityType) longestMatchFound)
private static void WalkNavigations(IEntityType entityType, IReadOnlyList <string> navigationPropertyPaths, IncludeLoadTree includeLoadTree) { var longestMatchFound = WalkNavigationsInternal(entityType, navigationPropertyPaths, includeLoadTree, new Stack <INavigation>(), new KeyValuePair <int, IEntityType>(0, null)); if (longestMatchFound.Key < navigationPropertyPaths.Count) { throw new InvalidOperationException( CoreStrings.IncludeBadNavigation(navigationPropertyPaths[longestMatchFound.Key], longestMatchFound.Value.DisplayName())); } }