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

  1. 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" ...).
  2. Make sure the raw SQL returns ALL columns EF maps for the entity (check the entity's column mappings / [Column] attributes and the migration).
  3. 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.
  4. Enable EF logging / inspect ToQueryString() to compare the expected column set against what your SQL actually returns.
  5. 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

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


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