{"record":{"id":"2910f9e74d5b9e48","repo":"dotnet/efcore","slug":"the-required-column-column-was-not-present-in-2910f9","errorCode":null,"errorMessage":"The required column '{column}' was not present in the results of a 'FromSql' operation.","messagePattern":"The required column '(.+?)' was not present in the results of a 'FromSql' operation\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Query/Internal/FromSqlQueryingEnumerable.cs","lineNumber":174,"sourceCode":"    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to\n    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in\n    ///     any release. You should only use it directly in your code with extreme caution and knowing that\n    ///     doing so can result in application failures when updating to a new Entity Framework Core release.\n    /// </summary>\n    public static int[] BuildIndexMap(IReadOnlyList<string> columnNames, DbDataReader dataReader)\n    {\n        var readerColumns = Enumerable.Range(0, dataReader.FieldCount)\n            .ToDictionary(dataReader.GetName, i => i, StringComparer.OrdinalIgnoreCase);\n\n        var indexMap = new int[columnNames.Count];\n        for (var i = 0; i < columnNames.Count; i++)\n        {\n            var columnName = columnNames[i];\n            if (!readerColumns.TryGetValue(columnName, out var ordinal))\n            {\n                if (columnNames.Count != 1)\n                {\n                    throw new InvalidOperationException(RelationalStrings.FromSqlMissingColumn(columnName));\n                }\n\n                ordinal = 0;\n            }\n\n            indexMap[i] = ordinal;\n        }\n\n        return indexMap;\n    }\n\n    private sealed class Enumerator : IEnumerator<T>\n    {\n        private readonly RelationalQueryContext _relationalQueryContext;\n        private readonly RelationalCommandResolver _relationalCommandResolver;\n        private readonly IReadOnlyList<ReaderColumn?>? _readerColumns;\n        private readonly IReadOnlyList<string> _columnNames;\n        private readonly Func<QueryContext, DbDataReader, int[], T> _shaper;","sourceCodeStart":156,"sourceCodeEnd":192,"githubUrl":"https://github.com/dotnet/efcore/blob/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Relational/Query/Internal/FromSqlQueryingEnumerable.cs#L156-L192","documentation":"Thrown when a FromSqlRaw/FromSqlInterpolated query returns a result set whose columns do not include a column EF expects. The BuildIndexMap method maps expected property column names to reader ordinals; when a name is not found and more than one column is expected, it throws. This signals a mismatch between the entity's mapped column names and the raw SQL's SELECT list.","triggerScenarios":"Calling DbContext.Set<T>().FromSqlRaw(\"SELECT ...\") or FromSqlInterpolated($\"SELECT ...\") where the raw SQL omits a column that the entity type has mapped, or names it differently (case is ignored, but spelling must match). Only thrown when the entity expects 2+ columns; with a single expected column, a missing name silently falls back to ordinal 0.","commonSituations":"Stored procedure whose result set was changed (column renamed/removed) but the entity model was not updated. Using SELECT * during a schema migration where a new non-nullable column was added to the entity but not yet to the sproc. Renaming a property via column mapping (HasColumnName) but forgetting to update the raw SQL. Mismatch between the FromSql SQL and a composed LINQ query that projects additional columns.","solutions":["Inspect the exception message for the exact column name, then ensure your raw SQL SELECT list includes that column with the expected name (matching HasColumnName if configured).","If using a stored procedure, update its SELECT list to return all columns the entity maps, or update the entity model to match the sproc's current output.","Use SELECT * from the table/view instead of an explicit column list so all mapped columns are included automatically.","If the column is intentionally absent, mark the property as nullable or remove it from the entity model, or use a DTO projection instead of the entity type.","Verify HasColumnName() configuration matches the actual SQL column names returned by the query."],"exampleFix":"// before\nvar blogs = context.Blogs\n    .FromSqlRaw(\"SELECT Id, Title FROM Blogs\")\n    .ToList(); // Blog entity has a 'CreatedAt' column\n\n// after\nvar blogs = context.Blogs\n    .FromSqlRaw(\"SELECT Id, Title, CreatedAt FROM Blogs\")\n    .ToList();","handlingStrategy":"validation","validationCode":"// Before calling FromSqlRaw, verify the SQL returns expected columns\n// by running a test that executes the SQL and checks the reader:\nusing var conn = context.Database.GetDbConnection();\nawait conn.OpenAsync();\nusing var cmd = conn.CreateCommand();\ncmd.CommandText = \"SELECT * FROM dbo.YourSprocOrView LIMIT 0\";\nusing var reader = await cmd.ExecuteReaderAsync();\nvar actualColumns = new HashSet<string>(StringComparer.OrdinalIgnoreCase);\nfor (var i = 0; i < reader.FieldCount; i++)\n    actualColumns.Add(reader.GetName(i));\nvar expectedColumns = context.Model.FindEntityType(typeof(Blog))!\n    .GetProperties().Select(p => p.GetColumnName()).ToList();\nvar missing = expectedColumns.Where(c => c != null && !actualColumns.Contains(c!)).ToList();\nif (missing.Any())\n    throw new InvalidOperationException($\"SQL is missing columns: {string.Join(\", \", missing)}\");","typeGuard":null,"tryCatchPattern":"try\n{\n    var result = context.Blogs.FromSqlRaw(sql, parameters).ToList();\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"was not present in the results of a 'FromSql'\"))\n{\n    logger.LogWarning(ex, \"FromSql column mismatch — verify SQL SELECT list matches entity mapping\");\n    throw;\n}","preventionTips":["Write an integration test that executes your raw SQL and asserts all expected entity columns are present.","Avoid hardcoding column lists in raw SQL; use SELECT * from the base table when possible.","When using stored procedures, keep the SELECT list in sync with the entity model via code reviews or schema tests.","Use HasHasColumnName consistently and document expected column names near the FromSql call."],"tags":["fromsql","raw-sql","column-mapping","schema-mismatch"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}