dotnet/efcore · error · InvalidOperationException

The required column ' ' was not present in the results of a…

Error message

The required column '{column}' was not present in the results of a 'FromSql' operation.

What it means

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.

Solutions

  1. 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).
  2. 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.
  3. Use SELECT * from the table/view instead of an explicit column list so all mapped columns are included automatically.
  4. 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.
  5. Verify HasColumnName() configuration matches the actual SQL column names returned by the query.

Example fix

// before
var blogs = context.Blogs
    .FromSqlRaw("SELECT Id, Title FROM Blogs")
    .ToList(); // Blog entity has a 'CreatedAt' column

// after
var blogs = context.Blogs
    .FromSqlRaw("SELECT Id, Title, CreatedAt FROM Blogs")
    .ToList();
Defensive patterns

Strategy: validation

Validate before calling

// Before calling FromSqlRaw, verify the SQL returns expected columns
// by running a test that executes the SQL and checks the reader:
using var conn = context.Database.GetDbConnection();
await conn.OpenAsync();
using var cmd = conn.CreateCommand();
cmd.CommandText = "SELECT * FROM dbo.YourSprocOrView LIMIT 0";
using var reader = await cmd.ExecuteReaderAsync();
var actualColumns = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
for (var i = 0; i < reader.FieldCount; i++)
    actualColumns.Add(reader.GetName(i));
var expectedColumns = context.Model.FindEntityType(typeof(Blog))!
    .GetProperties().Select(p => p.GetColumnName()).ToList();
var missing = expectedColumns.Where(c => c != null && !actualColumns.Contains(c!)).ToList();
if (missing.Any())
    throw new InvalidOperationException($"SQL is missing columns: {string.Join(", ", missing)}");

Try / catch

try
{
    var result = context.Blogs.FromSqlRaw(sql, parameters).ToList();
}
catch (InvalidOperationException ex) when (ex.Message.Contains("was not present in the results of a 'FromSql'"))
{
    logger.LogWarning(ex, "FromSql column mismatch — verify SQL SELECT list matches entity mapping");
    throw;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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

Appendix: 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 3a2006ef56)