private static IAsyncEnumerable <TResult> _GroupJoin <TOuter, TInner, TKey, TResult>( RelationalQueryContext queryContext, IAsyncEnumerable <ValueBuffer> source, IShaper <TOuter> outerShaper, IShaper <TInner> innerShaper, Func <TInner, TKey> innerKeySelector, Func <TOuter, IAsyncEnumerable <TInner>, TResult> resultSelector, AsyncGroupJoinInclude outerGroupJoinInclude, AsyncGroupJoinInclude innerGroupJoinInclude) => new GroupJoinAsyncEnumerable <TOuter, TInner, TKey, TResult>( queryContext, source, outerShaper, innerShaper, innerKeySelector, resultSelector, outerGroupJoinInclude, innerGroupJoinInclude);
public QueryingEnumerable(RelationalQueryContext relationalQueryContext, IQuerySqlGeneratorFactory querySqlGeneratorFactory, ISqlExpressionFactory sqlExpressionFactory, IParameterNameGeneratorFactory parameterNameGeneratorFactory, SelectExpression selectExpression, Func <QueryContext, DbDataReader, T, int[], ResultCoordinator, T> shaper, Type contextType, IDiagnosticsLogger <DbLoggerCategory.Query> logger) { _relationalQueryContext = relationalQueryContext; _querySqlGeneratorFactory = querySqlGeneratorFactory; _sqlExpressionFactory = sqlExpressionFactory; _parameterNameGeneratorFactory = parameterNameGeneratorFactory; _selectExpression = selectExpression; _shaper = shaper; _contextType = contextType; _logger = logger; }
internal static IAsyncEnumerable <T> _Include <T>( RelationalQueryContext queryContext, IAsyncEnumerable <T> innerResults, Func <T, object> entityAccessor, IReadOnlyList <INavigation> navigationPath, IReadOnlyList <Func <IAsyncIncludeRelatedValuesStrategy> > includeRelatedValuesStrategyFactories, bool querySourceRequiresTracking) { queryContext.BeginIncludeScope(); var includeRelatedValuesStrategies = includeRelatedValuesStrategyFactories .Select(f => f()) .ToList(); var relatedValueBuffers = includeRelatedValuesStrategies .Select <IAsyncIncludeRelatedValuesStrategy, AsyncRelatedEntitiesLoader>(s => s.GetRelatedValues) .ToArray(); return(innerResults .Select( async(result, cancellationToken) => { await queryContext.QueryBuffer .IncludeAsync( entityAccessor == null ? result : entityAccessor(result), // TODO: Compile time? navigationPath, relatedValueBuffers, cancellationToken, querySourceRequiresTracking); return result; }) .Finally(() => { foreach (var includeRelatedValuesStrategy in includeRelatedValuesStrategies) { includeRelatedValuesStrategy.Dispose(); } queryContext.EndIncludeScope(); })); }
internal static IEnumerable <T> _Include <T>( RelationalQueryContext queryContext, IEnumerable <T> innerResults, Func <T, object> entityAccessor, IReadOnlyList <INavigation> navigationPath, IReadOnlyList <Func <IIncludeRelatedValuesStrategy> > includeRelatedValuesStrategyFactories, bool querySourceRequiresTracking) { queryContext.BeginIncludeScope(); var includeRelatedValuesStrategies = includeRelatedValuesStrategyFactories .Select(f => f()) .ToList(); var relatedEntitiesLoaders = includeRelatedValuesStrategies .Select <IIncludeRelatedValuesStrategy, RelatedEntitiesLoader>(s => s.GetRelatedValues) .ToArray(); try { foreach (var innerResult in innerResults) { queryContext.QueryBuffer .Include( entityAccessor == null ? innerResult : entityAccessor(innerResult), // TODO: Compile time? navigationPath, relatedEntitiesLoaders, querySourceRequiresTracking); yield return(innerResult); } } finally // Need this to run even if innerResults is not fully consumed. { foreach (var includeRelatedValuesStrategy in includeRelatedValuesStrategies) { includeRelatedValuesStrategy.Dispose(); } queryContext.EndIncludeScope(); } }
public GroupJoinAsyncEnumerable( RelationalQueryContext queryContext, IAsyncEnumerable <ValueBuffer> source, IShaper <TOuter> outerShaper, IShaper <TInner> innerShaper, Func <TInner, TKey> innerKeySelector, Func <TOuter, IAsyncEnumerable <TInner>, TResult> resultSelector, AsyncGroupJoinInclude outerGroupJoinInclude, AsyncGroupJoinInclude innerGroupJoinInclude) { _queryContext = queryContext; _source = source; _outerShaper = outerShaper; _innerShaper = innerShaper; _innerKeySelector = innerKeySelector; _resultSelector = resultSelector; _outerGroupJoinInclude = outerGroupJoinInclude; _innerGroupJoinInclude = innerGroupJoinInclude; }
private static IAsyncEnumerable <T> _Include <T>( RelationalQueryContext queryContext, IAsyncEnumerable <T> innerResults, Func <T, object> entityAccessor, IReadOnlyList <INavigation> navigationPath, IReadOnlyList <Func <QueryContext, IAsyncRelatedEntitiesLoader> > relatedEntitiesLoaderFactories, bool querySourceRequiresTracking) { queryContext.BeginIncludeScope(); var relatedEntitiesLoaders = relatedEntitiesLoaderFactories.Select(f => f(queryContext)) .ToArray(); return(innerResults .Select( async(result, cancellationToken) => { await queryContext.QueryBuffer .IncludeAsync( queryContext, entityAccessor == null ? result : entityAccessor(result), // TODO: Compile time? navigationPath, relatedEntitiesLoaders, querySourceRequiresTracking, cancellationToken); return result; }) .Finally(() => { foreach (var relatedEntitiesLoader in relatedEntitiesLoaders) { relatedEntitiesLoader.Dispose(); } queryContext.EndIncludeScope(); })); }
private static IAsyncEnumerable <T> _Include <T>( RelationalQueryContext queryContext, IAsyncEnumerable <T> innerResults, Func <T, object> entityAccessor, IReadOnlyList <INavigation> navigationPath, IReadOnlyList <Func <QueryContext, IAsyncRelatedEntitiesLoader> > relatedEntitiesLoaderFactories, bool querySourceRequiresTracking) { queryContext.BeginIncludeScope(); var relatedEntitiesLoaders = relatedEntitiesLoaderFactories.Select(f => f(queryContext)) .ToArray(); return(new IncludeAsyncEnumerable <T>( queryContext, innerResults, entityAccessor, navigationPath, relatedEntitiesLoaders, querySourceRequiresTracking)); }
// ReSharper disable once InconsistentNaming private static IEnumerable <TEntity> _FastQuery <TEntity>( RelationalQueryContext relationalQueryContext, ShaperCommandContext shaperCommandContext, Func <DbDataReader, DbContext, TEntity> materializer, Type contextType, IDiagnosticsLogger <DbLoggerCategory.Query> logger) { relationalQueryContext.Connection.Open(); RelationalDataReader dataReader; try { var relationalCommand = shaperCommandContext .GetRelationalCommand(relationalQueryContext.ParameterValues, relationalQueryContext); dataReader = relationalCommand.ExecuteReader( relationalQueryContext.Connection, relationalQueryContext.ParameterValues, relationalQueryContext.CommandLogger); } catch { // If failure happens creating the data reader, then it won't be available to // handle closing the connection, so do it explicitly here to preserve ref counting. relationalQueryContext.Connection.Close(); throw; } var dbDataReader = dataReader.DbDataReader; try { using (dataReader) { using (relationalQueryContext.ConcurrencyDetector.EnterCriticalSection()) // TODO: IDisposable box? { while (true) { bool hasNext; try { hasNext = dataReader.Read(); } catch (Exception exception) { logger.QueryIterationFailed(contextType, exception); throw; } if (hasNext) { yield return(materializer(dbDataReader, relationalQueryContext.Context)); } else { yield break; } } } } } finally { relationalQueryContext.Connection?.Close(); relationalQueryContext.Dispose(); } }
// ReSharper disable once InconsistentNaming private static IEnumerable <TResult> _GroupJoin <TOuter, TInner, TKey, TResult>( RelationalQueryContext queryContext, IEnumerable <ValueBuffer> source, IShaper <TOuter> outerShaper, IShaper <TInner> innerShaper, Func <TInner, TKey> innerKeySelector, Func <TOuter, IEnumerable <TInner>, TResult> resultSelector, GroupJoinInclude outerGroupJoinInclude, GroupJoinInclude innerGroupJoinInclude) { var outerGroupJoinIncludeContext = outerGroupJoinInclude?.CreateIncludeContext(queryContext); var innerGroupJoinIncludeContext = innerGroupJoinInclude?.CreateIncludeContext(queryContext); try { using (var sourceEnumerator = source.GetEnumerator()) { var comparer = EqualityComparer <TKey> .Default; var hasNext = sourceEnumerator.MoveNext(); var nextOuter = default(TOuter); while (hasNext) { var outer = Equals(nextOuter, default(TOuter)) ? outerShaper.Shape(queryContext, sourceEnumerator.Current) : nextOuter; nextOuter = default(TOuter); outerGroupJoinIncludeContext?.Include(outer); var inner = innerShaper.Shape(queryContext, sourceEnumerator.Current); var inners = new List <TInner>(); if (inner == null) { yield return(resultSelector(outer, inners)); hasNext = sourceEnumerator.MoveNext(); } else { var currentGroupKey = innerKeySelector(inner); innerGroupJoinIncludeContext?.Include(inner); inners.Add(inner); while (true) { hasNext = sourceEnumerator.MoveNext(); if (!hasNext) { break; } nextOuter = outerShaper.Shape(queryContext, sourceEnumerator.Current); if (!Equals(outer, nextOuter)) { break; } nextOuter = default(TOuter); inner = innerShaper.Shape(queryContext, sourceEnumerator.Current); if (inner == null) { break; } var innerKey = innerKeySelector(inner); if (!comparer.Equals(currentGroupKey, innerKey)) { break; } innerGroupJoinIncludeContext?.Include(inner); inners.Add(inner); } yield return(resultSelector(outer, inners)); } } } } finally { innerGroupJoinIncludeContext?.Dispose(); outerGroupJoinIncludeContext?.Dispose(); } }