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 valuesView on GitHub (pinned to dbf9771522)
Solutions
- Use a real relational provider (SQL Server/SQLite/PostgreSQL) in the scenario where you need the DbCommand - InMemory cannot produce one.
- Ensure the query is fully translatable so EF keeps it in the relational pipeline (avoid client-side predicates/projections).
- Guard the provider before calling: check DbContext.Database.ProviderName is a relational provider, or check `context.Database.IsRelational()`.
- 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
- Use a relational provider (Sqlite/SqlServer) in any test that exercises CreateDbCommand.
- Guard with context.Database.IsRelational() before calling.
- Prefer ToQueryString() when you only need the SQL text.
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.