dotnet/efcore · error · InvalidOperationException
The required column '{column}' was not present in the result
Error message
The required column '{column}' was not present in the results of a 'FromSql' operation. What it means
Thrown by FromSqlQueryingEnumerable.BuildIndexMap when mapping the columns returned by a raw SQL result set to the columns EF expects for entity materialization. EF matches reader columns by name (case-insensitive), so every expected column name must appear in the data reader's output. When a name is missing and more than one column is expected, there is no safe fallback, so EF aborts rather than materialize a partially-null entity. This protects against silent data corruption from column-name mismatches in hand-written SQL.
Source
Thrown at src/EFCore.Relational/Query/Internal/FromSqlQueryingEnumerable.cs:174
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public static int[] BuildIndexMap(IReadOnlyList<string> columnNames, DbDataReader dataReader)
{
var readerColumns = Enumerable.Range(0, dataReader.FieldCount)
.ToDictionary(dataReader.GetName, i => i, StringComparer.OrdinalIgnoreCase);
var indexMap = new int[columnNames.Count];
for (var i = 0; i < columnNames.Count; i++)
{
var columnName = columnNames[i];
if (!readerColumns.TryGetValue(columnName, out var ordinal))
{
if (columnNames.Count != 1)
{
throw new InvalidOperationException(RelationalStrings.FromSqlMissingColumn(columnName));
}
ordinal = 0;
}
indexMap[i] = ordinal;
}
return indexMap;
}
private sealed class Enumerator : IEnumerator<T>
{
private readonly RelationalQueryContext _relationalQueryContext;
private readonly RelationalCommandResolver _relationalCommandResolver;
private readonly IReadOnlyList<ReaderColumn?>? _readerColumns;
private readonly IReadOnlyList<string> _columnNames;
private readonly Func<QueryContext, DbDataReader, int[], T> _shaper;View on GitHub (pinned to dbf9771522)
Solutions
- Inspect the exact column name in the error message, then make your FromSqlRaw SQL return a column with that name (use AS aliasing: SELECT user_id AS "Id" ...).
- Make sure the raw SQL returns ALL columns EF maps for the entity (check the entity's column mappings / [Column] attributes and the migration).
- If you intentionally return fewer columns, project into an anonymous type or a non-tracking DTO instead of the full entity, so EF does not expect the missing column.
- Enable EF logging / inspect ToQueryString() to compare the expected column set against what your SQL actually returns.
- Verify stored procedure / view definitions in the database match what the code assumes (schema drift).
Example fix
// before - 'LastName' column missing from result set, but EF needs it
var users = context.Users.FromSqlRaw("SELECT Id, FirstName FROM Users WHERE Active = 1").ToList();
// after - include every mapped column, aliasing to match EF's expected names
var users = context.Users
.FromSqlRaw("SELECT Id, FirstName, LastName, Email FROM Users WHERE Active = 1")
.ToList();
// or project only what you need into a DTO to avoid requiring all columns
var dtos = context.Database.SqlQueryRaw<UserDto>(
"SELECT Id, FirstName FROM Users WHERE Active = 1").ToList(); Defensive patterns
Strategy: validation
Validate before calling
// Before calling FromSqlRaw, verify your SQL returns the expected columns by name.
// Map the entity's expected column names and check against a dry-run reader.
var expectedCols = ctx.Model.FindEntityType(typeof(User))!
.GetProperties().Select(p => p.GetColumnName()).ToArray();
using var probe = ctx.Database.SqlQueryRaw<FormattableString>(userSql).AsAsyncEnumerable()...;
// Or simply: SELECT the columns and confirm via a one-off schema query:
// SELECT column_name FROM information_schema.columns WHERE table_name = 'Users'
foreach (var name in expectedCols)
if (!readerColumnNames.Contains(name, StringComparer.OrdinalIgnoreCase))
throw new InvalidOperationException($"FromSqlRaw result is missing column '{name}'"); Try / catch
try { var data = ctx.Users.FromSqlRaw(sql).ToList(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("not present in the results of a")) {
// A mapped column is missing from the raw SQL result set.
_logger.LogError(ex, "FromSqlRaw column mismatch; ensure SQL returns all mapped columns by name.");
throw; // or fall back to a projection DTO
} Prevention
- Keep raw SQL in sync with entity column mappings; add a test that runs the SQL and asserts all expected columns are present.
- Prefer FromSqlInterpolated and LINQ composition over wide hand-written SELECT * that may drift from the model.
- When changing a property or its column name, grep all FromSqlRaw strings for the old name.
- Project into DTOs/anonymous types when you intentionally return fewer columns.
When it happens
Trigger: Calling dbContext.Set<T>().FromSqlRaw("SELECT ...") or FromSqlInterpolated(...) where the raw SQL returns a result set whose column names do not include all the property/column names EF needs. Only fires when columnNames.Count != 1 (the single-column projection case falls back to ordinal 0 at line 177). Triggered when the SQL renames a column (e.g. SELECT Id AS UserId), omits a required column, or returns columns from a different table/shape than the entity.
Common situations: Switching a stored procedure or view whose columns were renamed; aliasing columns in raw SQL without matching EF property names; changing the entity model (renaming a property or its column mapping) while leaving old FromSqlRaw strings unchanged; returning a subset of columns from a JOIN in the raw SQL but projecting the full entity.
Related errors
- The required column '{column}' was not present in the result
- The underlying reader doesn't have as many fields as expecte
- The LINQ expression '{expression}' could not be translated.
- Including navigation '{navigation}' is not supported as the
- Unhandled expression '{expression}' of type '{expressionType
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/2910f9e74d5b9e48.
Report an issue: GitHub.