dotnet/efcore · error · InvalidOperationException

UnableToBindMemberToEntityProjection

UnableToBindMemberToEntityProjection

Error message

Unable to bind '{memberType}.{member}' to an entity projection of '{entityType}'.

What it means

Thrown by JsonQueryExpression.BindProperty (JsonQueryExpression.cs:131-132) when the property being bound does not belong (is not assignable to/from) the JSON structural type that the expression represents. EF needs the property to live on the JSON-mapped entity/complex type to resolve its JSON path; a property from an unrelated type cannot be bound, so EF aborts rather than emit a wrong path.

Source

Thrown at src/EFCore.Relational/Query/JsonQueryExpression.cs:131

    [EntityFrameworkInternal]
    public virtual IReadOnlyDictionary<IProperty, ColumnExpression>? KeyPropertyMap { get; }

    /// <inheritdoc />
    public override ExpressionType NodeType
        => ExpressionType.Extension;

    /// <inheritdoc />
    public override Type Type { get; }

    /// <summary>
    ///     Binds a property with this JSON query expression to get the SQL representation.
    /// </summary>
    public virtual SqlExpression BindProperty(IProperty property)
    {
        if (!StructuralType.IsAssignableFrom(property.DeclaringType)
            && !property.DeclaringType.IsAssignableFrom(StructuralType))
        {
            throw new InvalidOperationException(
                RelationalStrings.UnableToBindMemberToEntityProjection("property", property.Name, StructuralType.DisplayName()));
        }

        if (KeyPropertyMap?.TryGetValue(property, out var match) == true)
        {
            return match;
        }

        var element = GetJsonElement(property);

        return new JsonScalarExpression(
            JsonColumn,
            [.. Path, new PathSegment(element.PropertyName!)],
            property.ClrType.UnwrapNullableType(),
            element.StoreTypeMapping!,
            IsNullable || property.IsNullable);
    }

View on GitHub (pinned to dbf9771522)

Solutions

  1. Bind only properties that belong to the JSON structural type (same type or a base/derived assignable type).
  2. If the property moved during a refactor, regenerate/retranslate the query so the JSON expression is rebuilt for the correct structural type.
  3. For provider/extension authors, validate property.DeclaringType against the expression's StructuralType before calling BindProperty.
  4. Ensure the query references the correct entity type for the JSON column being queried.

Example fix

// before (provider/visitor code) - binding a property from a different type
var sql = jsonQueryExpr.BindProperty(propertyFromOtherType);

// after - bind a property that belongs to the JSON structural type
var propOnJsonType = jsonQueryExpr.StructuralType.FindProperty(propertyName)!;
var sql = jsonQueryExpr.BindProperty(propOnJsonType);
Defensive patterns

Strategy: validation

Validate before calling

// (Provider/visitor) Verify the property belongs to the JSON structural type before binding.
if (!jsonExpr.StructuralType.IsAssignableFrom(prop.DeclaringType)
    && !prop.DeclaringType.IsAssignableFrom(jsonExpr.StructuralType))
    throw new InvalidOperationException($"Property {prop.Name} not on {jsonExpr.StructuralType.DisplayName()}");
var sql = jsonExpr.BindProperty(prop);

Type guard

static bool PropertyBelongsTo(IProperty p, ITypeBase t)
    => t.IsAssignableFrom(p.DeclaringType) || p.DeclaringType.IsAssignableFrom(t);

Prevention

When it happens

Trigger: Calling JsonQueryExpression.BindProperty with an IProperty whose DeclaringType is neither the same as nor assignable to the expression's StructuralType. Surfaced by EF internals during JSON query translation when a member access resolves to a property on the wrong type, or by provider/extension code that binds mismatched properties.

Common situations: Bugs in custom providers or query-tree visitors that bind a property to a JSON expression of a different type; inherited/discriminator mismatches in TPH where a property's declaring type differs from the structural type; refactoring an entity hierarchy so a property moves to another type while stale JSON expressions linger.

Related errors


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