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
- Verify the property's DeclaringType matches the projected StructuralType.
- Call UpdateEntityType on the projection to switch to the correct derived type before binding.
- 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
- Always verify the property's DeclaringType matches the projection before binding.
- Narrow projections with UpdateEntityType before binding derived-type properties.
- Add internal assertions that catch mismatches during translator development.
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
- Complex projections in subqueries are currently unsupported.
- Invalid token type: ' '.
- The LINQ expression ' ' could not be translated. Either…
- The LINQ expression ' ' could not be translated. Either…
- The query uses 'NoTrackingWithIdentityResolution' and…
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)