{"record":{"id":"ba1cb60aa96452b3","repo":"dotnet/efcore","slug":"unabletobindmembertoentityprojection","errorCode":"UnableToBindMemberToEntityProjection","errorMessage":"Unable to bind '{memberType}.{member}' to an entity projection of '{entityType}'.","messagePattern":"Unable to bind '(.+?)\\.(.+?)' to an entity projection of '(.+?)'\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Query/JsonQueryExpression.cs","lineNumber":131,"sourceCode":"    [EntityFrameworkInternal]\n    public virtual IReadOnlyDictionary<IProperty, ColumnExpression>? KeyPropertyMap { get; }\n\n    /// <inheritdoc />\n    public override ExpressionType NodeType\n        => ExpressionType.Extension;\n\n    /// <inheritdoc />\n    public override Type Type { get; }\n\n    /// <summary>\n    ///     Binds a property with this JSON query expression to get the SQL representation.\n    /// </summary>\n    public virtual SqlExpression BindProperty(IProperty property)\n    {\n        if (!StructuralType.IsAssignableFrom(property.DeclaringType)\n            && !property.DeclaringType.IsAssignableFrom(StructuralType))\n        {\n            throw new InvalidOperationException(\n                RelationalStrings.UnableToBindMemberToEntityProjection(\"property\", property.Name, StructuralType.DisplayName()));\n        }\n\n        if (KeyPropertyMap?.TryGetValue(property, out var match) == true)\n        {\n            return match;\n        }\n\n        var element = GetJsonElement(property);\n\n        return new JsonScalarExpression(\n            JsonColumn,\n            [.. Path, new PathSegment(element.PropertyName!)],\n            property.ClrType.UnwrapNullableType(),\n            element.StoreTypeMapping!,\n            IsNullable || property.IsNullable);\n    }\n","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/dotnet/efcore/blob/dbf9771522148d61a2467854921bd5dc6f6e6916/src/EFCore.Relational/Query/JsonQueryExpression.cs#L113-L149","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Bind only properties that belong to the JSON structural type (same type or a base/derived assignable type).","If the property moved during a refactor, regenerate/retranslate the query so the JSON expression is rebuilt for the correct structural type.","For provider/extension authors, validate property.DeclaringType against the expression's StructuralType before calling BindProperty.","Ensure the query references the correct entity type for the JSON column being queried."],"exampleFix":"// before (provider/visitor code) - binding a property from a different type\nvar sql = jsonQueryExpr.BindProperty(propertyFromOtherType);\n\n// after - bind a property that belongs to the JSON structural type\nvar propOnJsonType = jsonQueryExpr.StructuralType.FindProperty(propertyName)!;\nvar sql = jsonQueryExpr.BindProperty(propOnJsonType);","handlingStrategy":"validation","validationCode":"// (Provider/visitor) Verify the property belongs to the JSON structural type before binding.\nif (!jsonExpr.StructuralType.IsAssignableFrom(prop.DeclaringType)\n    && !prop.DeclaringType.IsAssignableFrom(jsonExpr.StructuralType))\n    throw new InvalidOperationException($\"Property {prop.Name} not on {jsonExpr.StructuralType.DisplayName()}\");\nvar sql = jsonExpr.BindProperty(prop);","typeGuard":"static bool PropertyBelongsTo(IProperty p, ITypeBase t)\n    => t.IsAssignableFrom(p.DeclaringType) || p.DeclaringType.IsAssignableFrom(t);","tryCatchPattern":null,"preventionTips":["Always bind properties whose DeclaringType matches the JSON structural type.","After refactoring an entity hierarchy, retranslate queries so JSON expressions are rebuilt.","Provider authors: validate property.DeclaringType against StructuralType before BindProperty.","Add tests covering inheritance/TPH property binding on JSON columns."],"tags":["ef-core","json","query-expression","entity-projection","provider"],"analyzedSha":"dbf9771522148d61a2467854921bd5dc6f6e6916","analyzedAt":"2026-08-06T20:46:03.226Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}