Skip to content

Commit

Permalink
Query: Combine QueryingEnumerable for regular and non composed FromSq…
Browse files Browse the repository at this point in the history
…l case
  • Loading branch information
smitpatel committed Jun 11, 2019
1 parent 79d5039 commit 1fe8d0d
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 387 deletions.
39 changes: 35 additions & 4 deletions src/EFCore.Relational/Query/Pipeline/AsyncQueryingEnumerable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore.Diagnostics;
Expand All @@ -19,7 +20,7 @@ private class AsyncQueryingEnumerable<T> : IAsyncEnumerable<T>
{
private readonly RelationalQueryContext _relationalQueryContext;
private readonly SelectExpression _selectExpression;
private readonly Func<QueryContext, DbDataReader, ResultCoordinator, Task<T>> _shaper;
private readonly Func<QueryContext, DbDataReader, int[], ResultCoordinator, Task<T>> _shaper;
private readonly IQuerySqlGeneratorFactory _querySqlGeneratorFactory;
private readonly Type _contextType;
private readonly IDiagnosticsLogger<DbLoggerCategory.Query> _logger;
Expand All @@ -32,7 +33,7 @@ public AsyncQueryingEnumerable(
ISqlExpressionFactory sqlExpressionFactory,
IParameterNameGeneratorFactory parameterNameGeneratorFactory,
SelectExpression selectExpression,
Func<QueryContext, DbDataReader, ResultCoordinator, Task<T>> shaper,
Func<QueryContext, DbDataReader, int[], ResultCoordinator, Task<T>> shaper,
Type contextType,
IDiagnosticsLogger<DbLoggerCategory.Query> logger)
{
Expand All @@ -52,10 +53,11 @@ public IAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToke
private sealed class AsyncEnumerator : IAsyncEnumerator<T>
{
private RelationalDataReader _dataReader;
private int[] _indexMap;
private ResultCoordinator _resultCoordinator;
private readonly RelationalQueryContext _relationalQueryContext;
private readonly SelectExpression _selectExpression;
private readonly Func<QueryContext, DbDataReader, ResultCoordinator, Task<T>> _shaper;
private readonly Func<QueryContext, DbDataReader, int[], ResultCoordinator, Task<T>> _shaper;
private readonly IQuerySqlGeneratorFactory _querySqlGeneratorFactory;
private readonly Type _contextType;
private readonly IDiagnosticsLogger<DbLoggerCategory.Query> _logger;
Expand Down Expand Up @@ -104,6 +106,35 @@ public async ValueTask<bool> MoveNextAsync()
_relationalQueryContext.CommandLogger,
_cancellationToken);

if (selectExpression.IsNonComposedFromSql())
{
var projection = _selectExpression.Projection.ToList();
var readerColumns = Enumerable.Range(0, _dataReader.DbDataReader.FieldCount)
.ToDictionary(i => _dataReader.DbDataReader.GetName(i), i => i, StringComparer.OrdinalIgnoreCase);

_indexMap = new int[projection.Count];
for (var i = 0; i < projection.Count; i++)
{
if (projection[i].Expression is ColumnExpression columnExpression)
{
var columnName = columnExpression.Name;
if (columnName != null)
{
if (!readerColumns.TryGetValue(columnName, out var ordinal))
{
throw new InvalidOperationException(RelationalStrings.FromSqlMissingColumn(columnName));
}

_indexMap[i] = ordinal;
}
}
}
}
else
{
_indexMap = null;
}

_resultCoordinator = new ResultCoordinator();
}
catch (Exception)
Expand All @@ -121,7 +152,7 @@ public async ValueTask<bool> MoveNextAsync()

Current
= hasNext
? await _shaper(_relationalQueryContext, _dataReader.DbDataReader, _resultCoordinator)
? await _shaper(_relationalQueryContext, _dataReader.DbDataReader, _indexMap, _resultCoordinator)
: default;

return hasNext;
Expand Down

This file was deleted.

Loading

0 comments on commit 1fe8d0d

Please sign in to comment.