{"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/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Relational/Query/Internal/BufferedDataReader.cs#L1226-L1262","documentation":"Thrown by BufferedDataReader when the underlying reader returns fewer fields than the entity expects, yet none of the expected column names are individually missing (so the prior per-name check passed). This indicates a structural field-count deficit rather than a name mismatch.","triggerScenarios":"InitializeFields finds FieldCount < _columns.Count but every expected column name resolves in the lookup; the throw uses TooFewReaderFields. Typically a provider/driver returning a narrower shape than the mapped entity in non-composed FromSql.","commonSituations":"Driver-level column suppression (e.g. provider returns computed columns lazily). Provider version change that alters field reporting. Mismatched schema between two reads of the same query. Computed/unused columns not emitted by stored procedures.","solutions":["Ensure the SQL/procedure returns at least as many fields as the entity maps.","Reduce the entity's mapped property count to match what the query actually returns, or split into a DTO.","Update the database provider package so its reader reports fields consistently.","Confirm FieldCount semantics for the underlying DbDataReader against the active provider."],"exampleFix":"// before\nvar users = dbContext.Users.FromSqlInterpolated($\"EXEC dbo.GetUsers\").ToList();\n// procedure returns 2 cols but User maps 3\n\n// after: fix the procedure / SELECT to return all mapped columns\nvar users = dbContext.Users.FromSqlRaw(\"SELECT Id, Name, Email FROM Users\").ToList();","handlingStrategy":"validation","validationCode":"static void EnsureReaderFieldCount(DbDataReader reader, int expectedColumns)\n{\n    if (reader.FieldCount < expectedColumns)\n        throw new InvalidOperationException($\"Reader reports {reader.FieldCount} fields; expected at least {expectedColumns}.\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Make stored procedures/views return at least the mapped column count.","Verify provider behavior after package upgrades.","Prefer full-table SELECTs over narrow projections for entity materialization."],"tags":["ef-core","query","fromsql","reader-shape"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}