{"record":{"id":"0b376604087c3ee3","repo":"dotnet/efcore","slug":"table-name-must-be-specified-to-configure-a-table","errorCode":null,"errorMessage":"Table name must be specified to configure a table-specific property mapping.","messagePattern":"Table name must be specified to configure a table-specific property mapping\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Metadata/Builders/OwnedNavigationTableBuilder.cs","lineNumber":164,"sourceCode":"    /// <summary>\n    ///     Maps the property to a column on the current table and returns an object that can be used\n    ///     to provide table-specific configuration if the property is mapped to more than one table.\n    /// </summary>\n    /// <typeparam name=\"TProperty\">The type of the property to be configured.</typeparam>\n    /// <param name=\"propertyName\">The name of the property to be configured.</param>\n    /// <returns>An object that can be used to configure the property.</returns>\n    public virtual ColumnBuilder<TProperty> Property<TProperty>(string propertyName)\n        => new(GetStoreObjectIdentifier(), OwnedNavigationBuilder.Property<TProperty>(propertyName));\n\n    /// <summary>\n    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to\n    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in\n    ///     any release. You should only use it directly in your code with extreme caution and knowing that\n    ///     doing so can result in application failures when updating to a new Entity Framework Core release.\n    /// </summary>\n    [EntityFrameworkInternal]\n    protected virtual StoreObjectIdentifier GetStoreObjectIdentifier()\n        => StoreObject ?? throw new InvalidOperationException(RelationalStrings.MappingFragmentMissingName);\n\n    OwnedNavigationBuilder IInfrastructure<OwnedNavigationBuilder>.Instance\n        => OwnedNavigationBuilder;\n\n    #region Hidden System.Object members\n\n    /// <summary>\n    ///     Returns a string that represents the current object.\n    /// </summary>\n    /// <returns>A string that represents the current object.</returns>\n    [EditorBrowsable(EditorBrowsableState.Never)]\n    public override string? ToString()\n        => base.ToString();\n\n    /// <summary>\n    ///     Determines whether the specified object is equal to the current object.\n    /// </summary>\n    /// <param name=\"obj\">The object to compare with the current object.</param>","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/dotnet/efcore/blob/dbf9771522148d61a2467854921bd5dc6f6e6916/src/EFCore.Relational/Metadata/Builders/OwnedNavigationTableBuilder.cs#L146-L182","documentation":"Thrown by OwnedNavigationTableBuilder.GetStoreObjectIdentifier() at OwnedNavigationTableBuilder.cs:164 when the StoreObject property is null. This occurs when a table-specific property mapping is attempted on an owned navigation table builder that was not created with a specific table name (i.e., no ToTable call established the fragment).","triggerScenarios":"Calling .Property<T>(\"ColName\").HasColumnName(...) on an OwnedNavigationTableBuilder whose StoreObject is null — this happens when the builder was obtained without specifying a table, e.g., via an API path that doesn't pass a StoreObjectIdentifier.","commonSituations":"Attempting to override column mappings for a specific table on an owned navigation that hasn't been mapped to a named table fragment. Misusing the builder API by calling table-specific configuration before ToTable.","solutions":["Ensure the owned navigation is mapped to a specific table via .ToTable(\"TableName\") before calling table-specific property configuration.","Use the non-table-specific Property configuration directly on the owned navigation builder if you don't need per-table overrides."],"exampleFix":"// before: no table specified\nmodelBuilder.Entity<Order>()\n    .OwnsOne(o => o.Details, ob =>\n    {\n        // attempt table-specific override without a named table\n        ob.ToTable(\"OrderDetails\")\n          .Property(d => d.Notes)\n          .HasColumnName(\"d_notes\");\n    });\n// If the builder somehow has no StoreObject, ensure ToTable is called first.\n\n// after: always chain from the ToTable result\nmodelBuilder.Entity<Order>()\n    .OwnsOne(o => o.Details, ob =>\n    {\n        ob.ToTable(\"OrderDetails\", tb =>\n        {\n            tb.Property(d => d.Notes).HasColumnName(\"d_notes\");\n        });\n    });","handlingStrategy":"validation","validationCode":"// Ensure the OwnedNavigationTableBuilder has a store object before calling Property()\n// Always chain from the ToTable callback:\nmodelBuilder.Entity<Order>().OwnsOne(o => o.Details, ob =>\n{\n    ob.ToTable(\"OrderDetails\", tb =>\n    {\n        // 'tb' has a valid StoreObject here\n        tb.Property(d => d.Notes).HasColumnName(\"d_notes\");\n    });\n});","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always configure table-specific property overrides inside the ToTable(name, tb => {...}) callback.","Never store a TableBuilder reference and use it outside the callback scope."],"tags":["table-mapping","owned-navigation","configuration"],"analyzedSha":"dbf9771522148d61a2467854921bd5dc6f6e6916","analyzedAt":"2026-08-06T20:46:03.226Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}