dotnet/efcore · error · InvalidOperationException

Unable to bind ' ' ' ' to an entity projection of ' '.

Error message

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

What it means

StructuralTypeProjectionExpression.BindProperty throws when the supplied IProperty's declaring type is neither the same as, nor related to, the projection's StructuralType. The property does not belong to the entity being projected, so the provider cannot resolve a JSON path for it. This is normally raised by internal callers passing the wrong property.

Solutions

  1. Verify the property's DeclaringType matches the projected StructuralType.
  2. Call UpdateEntityType on the projection to switch to the correct derived type before binding.
  3. Check that the entity being queried is the one that owns the property.

Example fix

// before - property belongs to a derived type but projection is the base
var expr = baseProjection.BindProperty(derivedTypeProperty, clientEval: false);

// after - narrow the projection first
var derived = baseProjection.UpdateEntityType(derivedType);
var expr = derived.BindProperty(derivedTypeProperty, clientEval: false);
Defensive patterns

Strategy: validation

Validate before calling

// Before binding, ensure the property belongs to the structural type.
static bool CanBindProperty(StructuralTypeProjectionExpression p, IProperty prop)
    => p.StructuralType.IsAssignableFrom(prop.DeclaringType) || prop.DeclaringType.IsAssignableFrom(p.StructuralType);

Type guard

static bool PropertyBelongsToProjection(StructuralTypeProjectionExpression p, IProperty prop)
    => p.StructuralType.IsAssignableFrom(prop.DeclaringType) || prop.DeclaringType.IsAssignableFrom(p.StructuralType);

Prevention

When it happens

Trigger: Internal translator code calls BindProperty with a property whose DeclaringType differs from the projection's StructuralType, e.g. binding a sibling-entity property against the wrong projection.

Common situations: Inheritance or TPH scenarios where a derived type's property is bound against a base-type projection; translator bugs after model changes.

Related errors


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

Appendix: source

Thrown at src/EFCore.Cosmos/Query/Internal/Expressions/StructuralTypeProjectionExpression.cs:107

    ///     doing so can result in application failures when updating to a new Entity Framework Core release.
    /// </summary>
    public virtual Expression Update(Expression @object)
        => ReferenceEquals(@object, Object)
            ? this
            : new StructuralTypeProjectionExpression(@object, StructuralType);

    /// <summary>
    ///     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 virtual Expression BindProperty(IProperty property, bool clientEval)
    {
        if (!StructuralType.IsAssignableFrom(property.DeclaringType)
            && !property.DeclaringType.IsAssignableFrom(StructuralType))
        {
            throw new InvalidOperationException(
                CosmosStrings.UnableToBindMemberToEntityProjection("property", property.Name, StructuralType.DisplayName()));
        }

        if (!_propertyExpressionsMap.TryGetValue(property, out var expression))
        {
            expression = new ScalarAccessExpression(
                Object, property.GetJsonPropertyName(), property.ClrType, property.GetTypeMapping());
            _propertyExpressionsMap[property] = expression;
        }

        if (!clientEval
            // TODO: We shouldn't be returning null from here. See issues #17670 and #14121.
            && expression.PropertyName?.Length is null or 0)
        {
            // Non-persisted property can't be translated
            return null!;
        }

View on GitHub (pinned to 3a2006ef56)