dotnet/efcore · error · NotSupportedException

A DbCommand cannot be created for a non-relational query.

Error message

A DbCommand cannot be created for a non-relational query.

What it means

CreateDbCommand (RelationalQueryableExtensions.cs:44) throws NotSupportedException(RelationalStrings.NoDbCommand) when the executed query does not yield an IRelationalQueryingEnumerable. CreateDbCommand is a relational-only diagnostic API: it only works for queries that EF Core compiled through the relational pipeline. In-memory provider, in-memory compiled queries, pre-compilation, or a query that was rewritten to client-side all produce a non-relational enumerable and are rejected.

Source

Thrown at src/EFCore.Relational/Extensions/RelationalQueryableExtensions.cs:44

    ///         executed the command.
    ///     </para>
    ///     <para>
    ///         Note that DbCommand is an <see cref="IDisposable" /> object. The caller is responsible for disposing the returned
    ///         command.
    ///     </para>
    ///     <para>
    ///         This is only typically supported by queries generated by Entity Framework Core.
    ///     </para>
    ///     <para>
    ///         See <see href="https://aka.ms/efcore-docs-diagnostics">Logging, events, and diagnostics</see> for more information and examples.
    ///     </para>
    /// </remarks>
    /// <param name="source">The query source.</param>
    /// <returns>The query string for debugging.</returns>
    public static DbCommand CreateDbCommand(this IQueryable source)
        => source.Provider.Execute<IEnumerable>(source.Expression) is IRelationalQueryingEnumerable queryingEnumerable
            ? queryingEnumerable.CreateDbCommand()
            : throw new NotSupportedException(RelationalStrings.NoDbCommand);

    #region FromSql

    /// <summary>
    ///     Creates a LINQ query based on a raw SQL query.
    /// </summary>
    /// <remarks>
    ///     <para>
    ///         If the database provider supports composing on the supplied SQL, you can compose on top of the raw SQL query using
    ///         LINQ operators: <c>context.Blogs.FromSqlRaw("SELECT * FROM Blogs").OrderBy(b => b.Name)</c>.
    ///     </para>
    ///     <para>
    ///         As with any API that accepts SQL it is important to parameterize any user input to protect against a SQL injection
    ///         attack. You can include parameter place holders in the SQL query string and then supply parameter values as additional
    ///         arguments. Any parameter values you supply will automatically be converted to a <see cref="DbParameter" />.
    ///     </para>
    ///     <para>
    ///         However, <b>never</b> pass a concatenated or interpolated string (<c>$""</c>) with non-validated user-provided values

View on GitHub (pinned to dbf9771522)

Solutions

  1. Use a real relational provider (SQL Server/SQLite/PostgreSQL) in the scenario where you need the DbCommand - InMemory cannot produce one.
  2. Ensure the query is fully translatable so EF keeps it in the relational pipeline (avoid client-side predicates/projections).
  3. Guard the provider before calling: check DbContext.Database.ProviderName is a relational provider, or check `context.Database.IsRelational()`.
  4. If you only need the SQL text, use ToQueryString() which also requires a relational provider but is more explicit.

Example fix

// before (with InMemory provider)
var cmd = context.Blogs.CreateDbCommand(); // throws NotSupportedException

// after
if (context.Database.IsRelational())
{
    var cmd = context.Blogs.CreateDbCommand();
    using (cmd) { /* ... */ }
}
// or switch the test fixture to UseSqlite/in-memory SQLite
Defensive patterns

Strategy: type-guard

Validate before calling

if (!context.Database.IsRelational())
{
    // CreateDbCommand is not available; fall back or skip.
    return null;
}
using var cmd = query.CreateDbCommand();

Type guard

static bool CanCreateDbCommand(DbContext ctx) => ctx.Database.IsRelational();

Prevention

When it happens

Trigger: Calling query.CreateDbCommand() when the DbContext uses the InMemory provider (or any non-relational provider), when the query was evaluated client-side, or when the IQueryable is not an EF query at all.

Common situations: Unit tests using UseInMemoryDatabase that call CreateDbCommand; integration-test helper that assumes a relational provider; calling CreateDbCommand on a query that EF couldn't translate and fell back to client eval; provider-agnostic library code.

Related errors


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