{"record":{"id":"da0f4ed49aa5ca4d","repo":"dotnet/efcore","slug":"the-underlying-reader-doesn-t-have-as-many-fields","errorCode":null,"errorMessage":"The underlying reader doesn't have as many fields as expected. Expected: {expected}, actual: {actual}.","messagePattern":"The underlying reader doesn't have as many fields as expected\\. Expected: (.+?), actual: (.+?)\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Query/Internal/BufferedDataReader.cs","lineNumber":1244,"sourceCode":"                return index;\n            }\n        }\n\n        private void InitializeFields()\n        {\n            var fieldCount = FieldCount;\n            if (FieldCount < _columns.Count)\n            {\n                // Non-composed FromSql\n                var readerColumns = _fieldNameLookup.Value;\n\n                var firstMissingColumn = _columns.Select(c => c?.Name).FirstOrDefault(c => c != null && !readerColumns.ContainsKey(c));\n                if (firstMissingColumn != null)\n                {\n                    throw new InvalidOperationException(RelationalStrings.FromSqlMissingColumn(firstMissingColumn));\n                }\n\n                throw new InvalidOperationException(RelationalStrings.TooFewReaderFields(_columns.Count, FieldCount));\n            }\n\n            _columnTypeCases = Enumerable.Repeat(TypeCase.Empty, fieldCount).ToArray();\n            _ordinalToIndexMap = Enumerable.Repeat(-1, fieldCount).ToArray();\n            if (_columns.Count > 0\n                && _columns.Any(e => e?.Name != null))\n            {\n                // Non-Composed FromSql\n                var readerColumns = _fieldNameLookup.Value;\n\n                _indexMap = new int[_columns.Count];\n                var newColumnMap = new ReaderColumn?[fieldCount];\n                for (var i = 0; i < _columns.Count; i++)\n                {\n                    var column = _columns[i];\n                    if (column == null)\n                    {\n                        continue;","sourceCodeStart":1226,"sourceCodeEnd":1262,"githubUrl":"https://github.com/dotnet/efcore/blob/dbf9771522148d61a2467854921bd5dc6f6e6916/src/EFCore.Relational/Query/Internal/BufferedDataReader.cs#L1226-L1262","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Return the full set of expected columns from your SQL/stored proc (match the entity's mapped columns).","Update the raw SQL to include all columns the shaper expects, or switch to a DTO projection.","If the schema intentionally has fewer columns, change the model so the shaper's expected column count matches."],"exampleFix":"// before\nvar rows = ctx.Users.FromSqlRaw(\"SELECT Id FROM Users\").ToList();\n// shaper expects 3 columns, reader returns 1 -> throws\n\n// after\nvar rows = ctx.Users.FromSqlRaw(\"SELECT Id, Name, Email FROM Users\").ToList();","handlingStrategy":"validation","validationCode":"var expected = dbContext.Model.FindEntityType(typeof(User))!.GetProperties().Count();\nusing var cmd = dbContext.Database.GetDbConnection().CreateCommand();\ncmd.CommandText = sql;\nawait dbContext.Database.OpenConnectionAsync();\nusing var probe = await cmd.ExecuteReaderAsync();\nif (probe.FieldCount < expected)\n    throw new InvalidOperationException($\"FromSql returns {probe.FieldCount} fields, shaper expects {expected}.\");","typeGuard":null,"tryCatchPattern":"try { return ctx.Users.FromSqlRaw(sql).ToList(); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"doesn't have as many fields as expected\"))\n{ _logger.LogError(ex, \"FromSql field count mismatch; widen the SELECT list.\"); throw; }","preventionTips":["Keep raw SQL SELECT lists in sync with the entity's mapped columns.","For stored procs, version-control the result-set contract and test it."],"tags":["efcore","query","fromsql","schema-mismatch","materialization"],"analyzedSha":"dbf9771522148d61a2467854921bd5dc6f6e6916","analyzedAt":"2026-08-06T20:46:03.226Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}