{"record":{"id":"6959193c8c20ea0e","repo":"dotnet/efcore","slug":"the-entity-type-entitytype-cannot-be-instantia","errorCode":null,"errorMessage":"The entity type '{entityType}' cannot be instantiated because its corresponding CLR type is abstract, but the entity type was mapped to '{storeObject}' using the 'TPC' mapping strategy. Only instantiable types should be mapped. See https://go.microsoft.com/fwlink/?linkid=2130430 for more information.","messagePattern":"The entity type '(.+?)' cannot be instantiated because its corresponding CLR type is abstract, but the entity type was mapped to '(.+?)' using the 'TPC' mapping strategy\\. Only instantiable types should be mapped\\. See https://go\\.microsoft\\.com/fwlink/\\?linkid=2130430 for more information\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Extensions/RelationalEntityTypeBuilderExtensions.UseSproc.cs","lineNumber":934,"sourceCode":"\n        return entityTypeBuilder;\n    }\n\n    private static EntityTypeBuilder<TEntity> UseStoredProcedure<TEntity>(\n        EntityTypeBuilder<TEntity> entityTypeBuilder,\n        string? name,\n        string? schema,\n        StoreObjectType sprocType,\n        Action<StoredProcedureBuilder<TEntity>> buildAction)\n        where TEntity : class\n    {\n        Check.NotNull(buildAction);\n\n        var entityType = entityTypeBuilder.Metadata;\n        if (entityType.GetMappingStrategy() == RelationalAnnotationNames.TpcMappingStrategy\n            && !entityType.ClrType.IsInstantiable())\n        {\n            throw new InvalidOperationException(\n                RelationalStrings.AbstractTpc(entityType.DisplayName(), name ?? sprocType.ToString()));\n        }\n\n        var sprocBuilder = InternalStoredProcedureBuilder.HasStoredProcedure(\n            entityType, sprocType, name, schema);\n        buildAction(new StoredProcedureBuilder<TEntity>(sprocBuilder.Metadata, entityTypeBuilder));\n\n        return entityTypeBuilder;\n    }\n\n    private static OwnedNavigationBuilder UseStoredProcedure(\n        OwnedNavigationBuilder ownedNavigationBuilder,\n        string? name,\n        string? schema,\n        StoreObjectType sprocType,\n        Action<OwnedNavigationStoredProcedureBuilder> buildAction)\n    {\n        Check.NotNull(buildAction);","sourceCodeStart":916,"sourceCodeEnd":952,"githubUrl":"https://github.com/dotnet/efcore/blob/dbf9771522148d61a2467854921bd5dc6f6e6916/src/EFCore.Relational/Extensions/RelationalEntityTypeBuilderExtensions.UseSproc.cs#L916-L952","documentation":"Stored-procedure mapping (Insert/Update/DeleteUsingStoredProcedure) is rejected for an abstract entity type that is mapped with the TPC (Table-per-Concrete-type) strategy. In TPC each concrete leaf type gets its own table, so an abstract base can never be instantiated or have a row written via a sproc; mapping a sproc onto it is a modeling error (RelationalEntityTypeBuilderExtensions.UseSproc.cs:934, RelationalStrings.AbstractTpc).","triggerScenarios":"Calling InsertUsingStoredProcedure<TEntity>/UpdateUsingStoredProcedure<TEntity>/DeleteUsingStoredProcedure<TEntity> on an abstract base class TEntity whose hierarchy is configured with UseTpcMappingStrategy().","commonSituations":"Refactoring an existing TPH/TPT hierarchy to TPC while leaving the stored-procedure configuration on the abstract base; applying a shared configuration action to all entity types in a hierarchy without filtering out the abstract root; scaffolding/configuring sprocs generically across IEntityType instances.","solutions":["Move the *UsingStoredProcedure configuration to each concrete (non-abstract) derived entity type instead of the abstract base.","Guard the call: only configure the sproc when entityType.ClrType.IsInstantiable() is true.","If the base must define the mapping contract, use a shared partial OnModelCreating applied per concrete type, not on the abstract root."],"exampleFix":"// before\nmodelBuilder.Entity<AnimalBase>()            // AnimalBase is abstract, TPC\n    .ToTable((\"Animals\", \"dbo\"))\n    .UseTpcMappingStrategy()\n    .InsertUsingStoredProcedure(\"InsertAnimal\", b => { ... });\n\n// after (configure sprocs on each concrete type)\nmodelBuilder.Entity<AnimalBase>().UseTpcMappingStrategy();\nmodelBuilder.Entity<Dog>()\n    .InsertUsingStoredProcedure(\"InsertDog\", b => { ... });\nmodelBuilder.Entity<Cat>()\n    .InsertUsingStoredProcedure(\"InsertCat\", b => { ... });","handlingStrategy":"validation","validationCode":"if (typeof(TEntity).IsAbstract\n    && entityType.GetMappingStrategy() == RelationalAnnotationNames.TpcMappingStrategy)\n{\n    throw new InvalidOperationException(\"Abstract TPC base cannot be sproc-mapped.\");\n}\n// only configure sprocs for instantiable types\nif (typeof(TEntity).IsInstantiable())\n{\n    builder.Entity<TEntity>().InsertUsingStoredProcedure(...);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Apply sproc configuration per concrete type, not on an abstract base.","When looping over entity types to configure sprocs, skip entityType.ClrType.IsAbstract.","Keep TPC strategy configuration separate from sproc configuration on the base."],"tags":["tpc-mapping","stored-procedures","inheritance","model-building"],"analyzedSha":"dbf9771522148d61a2467854921bd5dc6f6e6916","analyzedAt":"2026-08-06T20:46:03.226Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}