{"record":{"id":"fe27248a73177bb1","repo":"dotnet/efcore","slug":"entitytype-is-mapped-to-the-database-function","errorCode":null,"errorMessage":"'{entityType}' is mapped to the database function '{function}' while '{otherEntityType}' is mapped to the database function '{otherFunction}'. Map all the entity types in the hierarchy to the same database function. See https://go.microsoft.com/fwlink/?linkid=2130430 for more information.","messagePattern":"'(.+?)' is mapped to the database function '(.+?)' while '(.+?)' is mapped to the database function '(.+?)'\\. Map all the entity types in the hierarchy to the same database function\\. See https://go\\.microsoft\\.com/fwlink/\\?linkid=2130430 for more information\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs","lineNumber":2340,"sourceCode":"                }\n\n                continue;\n            }\n\n            switch (storeObjectType)\n            {\n                case StoreObjectType.Table:\n                    throw new InvalidOperationException(\n                        RelationalStrings.TphTableMismatch(\n                            entityType.DisplayName(), entityId.Value.DisplayName(),\n                            rootEntityType.DisplayName(), rootId?.DisplayName()));\n                case StoreObjectType.View:\n                    throw new InvalidOperationException(\n                        RelationalStrings.TphViewMismatch(\n                            entityType.DisplayName(), entityId.Value.DisplayName(),\n                            rootEntityType.DisplayName(), rootId?.DisplayName()));\n                case StoreObjectType.Function:\n                    throw new InvalidOperationException(\n                        RelationalStrings.TphDbFunctionMismatch(\n                            entityType.DisplayName(), entityId.Value.DisplayName(),\n                            rootEntityType.DisplayName(), rootId?.DisplayName()));\n                case StoreObjectType.InsertStoredProcedure:\n                case StoreObjectType.DeleteStoredProcedure:\n                case StoreObjectType.UpdateStoredProcedure:\n                    throw new InvalidOperationException(\n                        RelationalStrings.TphStoredProcedureMismatch(\n                            entityType.DisplayName(), entityId.Value.DisplayName(),\n                            rootEntityType.DisplayName(), rootId?.DisplayName()));\n            }\n        }\n    }\n\n    /// <inheritdoc />\n    protected override bool IsRedundant(IForeignKey foreignKey)\n        => base.IsRedundant(foreignKey)\n            && !foreignKey.DeclaringEntityType.GetMappingFragments().Any();","sourceCodeStart":2322,"sourceCodeEnd":2358,"githubUrl":"https://github.com/dotnet/efcore/blob/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs#L2322-L2358","documentation":"Thrown inside ValidateTphMapping when a derived type resolves to a different Function StoreObjectIdentifier than the root. TPH requires the whole hierarchy to share the same database function mapping; a derived type mapped to another function breaks the invariant.","triggerScenarios":"A TPH hierarchy where the root and a derived type map to different DB functions (e.g. via ToFunction or DbFunction mappings resolving to different StoreObjectIdentifiers).","commonSituations":"Configuring per-type DbFunction/ToFunction mappings while remaining on TPH; refactor that split function mappings across the hierarchy.","solutions":["Map the derived type to the same function as the root.","Switch the hierarchy to TPT/TPC if separate functions per type are intended.","Remove the extra function mapping on the derived type."],"exampleFix":"// before\nmodelBuilder.Entity<Person>().ToFunction(\"fn_People\");\nmodelBuilder.Entity<Customer>().ToFunction(\"fn_Customers\"); // throws 434\n\n// after (shared function under TPH)\nmodelBuilder.Entity<Person>().ToFunction(\"fn_People\");\n// derived Customer inherits fn_People\n// or switch to TPT for separate functions","handlingStrategy":"validation","validationCode":"foreach (var root in modelBuilder.Model.GetEntityTypes().Where(t => t.BaseType == null))\n{\n    if (root.FindDiscriminatorProperty() == null) continue;\n    var rootSo = StoreObjectIdentifier.Create(root, StoreObjectType.Function);\n    if (rootSo == null) continue;\n    foreach (var et in root.GetDerivedTypes())\n    {\n        var so = StoreObjectIdentifier.Create(et, StoreObjectType.Function);\n        if (so != null && so.Value != rootSo.Value)\n            throw new InvalidOperationException($\"{et.DisplayName()} function {so.Value.DisplayName()} differs from root {rootSo.Value.DisplayName()} (TPH).\");\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["In TPH, keep DbFunction/ToFunction mapping only on the root.","Switch to TPT/TPC if separate functions per type are required.","Validate function-mapping consistency in a model test."],"tags":["ef-core","model-validation","mapping","inheritance","tph","dbfunctions"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}