Skip to content

Commit

Permalink
Relational: Populate collections in projection before calling into cl…
Browse files Browse the repository at this point in the history
…ient code

The shapers on relational now take ResultContext which stores object[] of temporary values. Then populate the collection fully. Then call into client code to generate final result.

Resolves #16318
  • Loading branch information
smitpatel committed Aug 17, 2019
1 parent 53073a2 commit 8fcd992
Show file tree
Hide file tree
Showing 16 changed files with 583 additions and 381 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ private class AsyncQueryingEnumerable<T> : IAsyncEnumerable<T>
{
private readonly RelationalQueryContext _relationalQueryContext;
private readonly SelectExpression _selectExpression;
private readonly Func<QueryContext, DbDataReader, T, int[], ResultCoordinator, T> _shaper;
private readonly Func<QueryContext, DbDataReader, ResultContext, int[], ResultCoordinator, T> _shaper;
private readonly IQuerySqlGeneratorFactory _querySqlGeneratorFactory;
private readonly Type _contextType;
private readonly IDiagnosticsLogger<DbLoggerCategory.Query> _logger;
Expand All @@ -32,7 +32,7 @@ public AsyncQueryingEnumerable(
ISqlExpressionFactory sqlExpressionFactory,
IParameterNameGeneratorFactory parameterNameGeneratorFactory,
SelectExpression selectExpression,
Func<QueryContext, DbDataReader, T, int[], ResultCoordinator, T> shaper,
Func<QueryContext, DbDataReader, ResultContext, int[], ResultCoordinator, T> shaper,
Type contextType,
IDiagnosticsLogger<DbLoggerCategory.Query> logger)
{
Expand All @@ -56,7 +56,7 @@ private sealed class AsyncEnumerator : IAsyncEnumerator<T>
private ResultCoordinator _resultCoordinator;
private readonly RelationalQueryContext _relationalQueryContext;
private readonly SelectExpression _selectExpression;
private readonly Func<QueryContext, DbDataReader, T, int[], ResultCoordinator, T> _shaper;
private readonly Func<QueryContext, DbDataReader, ResultContext, int[], ResultCoordinator, T> _shaper;
private readonly IQuerySqlGeneratorFactory _querySqlGeneratorFactory;
private readonly Type _contextType;
private readonly IDiagnosticsLogger<DbLoggerCategory.Query> _logger;
Expand Down Expand Up @@ -147,15 +147,22 @@ public async ValueTask<bool> MoveNextAsync()
{
_resultCoordinator.ResultReady = true;
_resultCoordinator.HasNext = null;
Current = _shaper(_relationalQueryContext, _dataReader.DbDataReader, Current, _indexMap, _resultCoordinator);
Current = _shaper(_relationalQueryContext, _dataReader.DbDataReader,
_resultCoordinator.ResultContext, _indexMap, _resultCoordinator);
if (_resultCoordinator.ResultReady)
{
// We generated a result so null out previously stored values
_resultCoordinator.ResultContext.Values = null;
break;
}

if (!await _dataReader.ReadAsync())
{
_resultCoordinator.HasNext = false;
// Enumeration has ended, materialize last element
_resultCoordinator.ResultReady = true;
Current = _shaper(_relationalQueryContext, _dataReader.DbDataReader,
_resultCoordinator.ResultContext, _indexMap, _resultCoordinator);

break;
}
Expand Down
Loading

0 comments on commit 8fcd992

Please sign in to comment.