dotnet/efcore · error · InvalidOperationException

The underlying reader doesn't have as many fields as expecte

Error message

The underlying reader doesn't have as many fields as expected. Expected: {expected}, actual: {actual}.

What it means

Thrown in BufferedDataRecord.InitializeFields when the underlying reader has fewer fields than EF's _columns list expects, but no single expected column name is identifiable as missing (the reader column lookup did not flag a specific one). EF reports expected vs. actual field counts because it cannot align its shaper to the smaller result set.

Source

Thrown at src/EFCore.Relational/Query/Internal/BufferedDataReader.cs:1244

                return index;
            }
        }

        private void InitializeFields()
        {
            var fieldCount = FieldCount;
            if (FieldCount < _columns.Count)
            {
                // Non-composed FromSql
                var readerColumns = _fieldNameLookup.Value;

                var firstMissingColumn = _columns.Select(c => c?.Name).FirstOrDefault(c => c != null && !readerColumns.ContainsKey(c));
                if (firstMissingColumn != null)
                {
                    throw new InvalidOperationException(RelationalStrings.FromSqlMissingColumn(firstMissingColumn));
                }

                throw new InvalidOperationException(RelationalStrings.TooFewReaderFields(_columns.Count, FieldCount));
            }

            _columnTypeCases = Enumerable.Repeat(TypeCase.Empty, fieldCount).ToArray();
            _ordinalToIndexMap = Enumerable.Repeat(-1, fieldCount).ToArray();
            if (_columns.Count > 0
                && _columns.Any(e => e?.Name != null))
            {
                // Non-Composed FromSql
                var readerColumns = _fieldNameLookup.Value;

                _indexMap = new int[_columns.Count];
                var newColumnMap = new ReaderColumn?[fieldCount];
                for (var i = 0; i < _columns.Count; i++)
                {
                    var column = _columns[i];
                    if (column == null)
                    {
                        continue;

View on GitHub (pinned to dbf9771522)

Solutions

  1. Return the full set of expected columns from your SQL/stored proc (match the entity's mapped columns).
  2. Update the raw SQL to include all columns the shaper expects, or switch to a DTO projection.
  3. If the schema intentionally has fewer columns, change the model so the shaper's expected column count matches.

Example fix

// before
var rows = ctx.Users.FromSqlRaw("SELECT Id FROM Users").ToList();
// shaper expects 3 columns, reader returns 1 -> throws

// after
var rows = ctx.Users.FromSqlRaw("SELECT Id, Name, Email FROM Users").ToList();
Defensive patterns

Strategy: validation

Validate before calling

var expected = dbContext.Model.FindEntityType(typeof(User))!.GetProperties().Count();
using var cmd = dbContext.Database.GetDbConnection().CreateCommand();
cmd.CommandText = sql;
await dbContext.Database.OpenConnectionAsync();
using var probe = await cmd.ExecuteReaderAsync();
if (probe.FieldCount < expected)
    throw new InvalidOperationException($"FromSql returns {probe.FieldCount} fields, shaper expects {expected}.");

Try / catch

try { return ctx.Users.FromSqlRaw(sql).ToList(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("doesn't have as many fields as expected"))
{ _logger.LogError(ex, "FromSql field count mismatch; widen the SELECT list."); throw; }

Prevention

When it happens

Trigger: A FromSql query returning fewer columns than the entity/shaper expects; a reader whose FieldCount is less than the configured column count; a mismatch between the shaper's expected columns and the actual SQL projection when names line up only partially.

Common situations: Stored procedures whose result set was trimmed; hand-written SQL that aliases/reduces columns; entity with newly added properties not reflected in the raw SQL; provider returning a degenerate reader.

Related errors


AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06). Data as JSON: /api/errors/da0f4ed49aa5ca4d. Report an issue: GitHub.