dotnet/efcore · error · InvalidOperationException
'{operation}' used over owned type '{entityType}' which is m
Error message
'{operation}' used over owned type '{entityType}' which is mapped to JSON; '{operation}' on JSON-mapped owned entities is not supported. Consider mapping your type as a complex type instead. What it means
TranslateExecuteDelete checks entityType.IsMappedToJson() and refuses to delete JSON-mapped owned entities. JSON-mapped owned data lives as a JSON document inside the owner's column; deleting it independently of the owner is not a meaningful server operation in EF's model. The message suggests complex types as an alternative mapping.
Source
Thrown at src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.ExecuteDelete.cs:22
using Microsoft.EntityFrameworkCore.Query.SqlExpressions;
namespace Microsoft.EntityFrameworkCore.Query;
public partial class RelationalQueryableMethodTranslatingExpressionVisitor
{
/// <inheritdoc />
protected override DeleteExpression TranslateExecuteDelete(ShapedQueryExpression source)
{
source = source.UpdateShaperExpression(new IncludePruner().Visit(source.ShaperExpression));
if (source.ShaperExpression is not StructuralTypeShaperExpression { StructuralType: IEntityType entityType } shaper)
{
throw new InvalidOperationException(RelationalStrings.ExecuteDeleteOnNonEntityType);
}
if (entityType.IsMappedToJson())
{
throw new InvalidOperationException(
RelationalStrings.ExecuteOperationOnOwnedJsonIsNotSupported("ExecuteDelete", entityType.DisplayName()));
}
switch (entityType.GetMappingStrategy())
{
case RelationalAnnotationNames.TptMappingStrategy:
throw new InvalidOperationException(
RelationalStrings.ExecuteOperationOnTPT(
nameof(EntityFrameworkQueryableExtensions.ExecuteDelete),
entityType.DisplayName()));
// Note that we do allow TPC if the target is a leaf type
case RelationalAnnotationNames.TpcMappingStrategy when entityType.GetDirectlyDerivedTypes().Any():
throw new InvalidOperationException(
RelationalStrings.ExecuteOperationOnTPC(
nameof(EntityFrameworkQueryableExtensions.ExecuteDelete),
entityType.DisplayName()));
}View on GitHub (pinned to 3a2006ef56)
Solutions
- Delete the owner entity (which removes its JSON document), or update the owner to null/remove the element from the collection via SaveChanges.
- If independent deletes are required, remap the owned type to its own table (ToTable) or use a complex type instead of .ToJson().
- Use raw SQL to mutate the JSON document if a partial JSON delete is needed (database-specific JSON functions).
Example fix
// before (delete JSON-mapped owned)
await db.Owners
.SelectMany(o => o.Tags /* OwnsMany().ToJson() */)
.ExecuteDeleteAsync();
// after (delete owner, or remap owned to a table)
await db.Owners.Where(o => o.Id == id).ExecuteDeleteAsync(); Defensive patterns
Strategy: validation
Validate before calling
// Block ExecuteDelete on JSON-mapped owned entities up front.
var et = db.Model.FindEntityType(typeof(TEntity))!;
if (et.IsMappedToJson())
throw new InvalidOperationException(
$"{et.Name} is JSON-mapped; delete the owner or remap to a table/complex type."); Prevention
- Delete the owner entity for JSON-mapped owned data.
- Use OwnsMany(...).ToJson() only for read-heavy data you never bulk-delete independently.
- Consider complex types for owned data that needs simpler lifecycle.
When it happens
Trigger: context.Owners.SelectMany(o => o.JsonCollection).ExecuteDelete() where JsonCollection is an OwnsMany(...).ToJson() navigation; calling ExecuteDelete on a query rooted at a JSON-mapped owned entity; targeting an owned entity mapped via .ToJson().
Common situations: Treating a JSON collection as a regular related entity and attempting bulk delete; refactoring from table-splitting to JSON mapping and reusing an existing ExecuteDelete call.
Related errors
- This node should be handled by provider-specific SQL generat
- SelectExpression can only be built over a JsonQueryExpressio
- The operation '{operation}' is being applied on entity type
- The operation '{operation}' is being applied on entity type
- The operation '{operation}' is being applied on entity type
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/576b807b0d95fc8a.
Report an issue: GitHub.