{"record":{"id":"9aff8508d0c9c6c9","repo":"dotnet/efcore","slug":"the-entity-type-entitytype-is-mapped-to-a-sql","errorCode":null,"errorMessage":"The entity type '{entityType}' is mapped to a SQL query, but is derived from '{baseEntityType}'. Derived entity types cannot be mapped to a different SQL query than the base entity type.","messagePattern":"The entity type '(.+?)' is mapped to a SQL query, but is derived from '(.+?)'\\. Derived entity types cannot be mapped to a different SQL query than the base entity type\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs","lineNumber":336,"sourceCode":"    ///     Validates the SQL query mapping for an entity type.\n    /// </summary>\n    /// <param name=\"entityType\">The entity type to validate.</param>\n    /// <param name=\"logger\">The logger to use.</param>\n    protected virtual void ValidateSqlQuery(\n        IEntityType entityType,\n        IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)\n    {\n        var sqlQuery = entityType.GetSqlQuery();\n        if (sqlQuery == null)\n        {\n            return;\n        }\n\n        if (entityType.BaseType != null\n            && (entityType.FindDiscriminatorProperty() == null\n                || sqlQuery != entityType.BaseType.GetSqlQuery()))\n        {\n            throw new InvalidOperationException(\n                RelationalStrings.InvalidMappedSqlQueryDerivedType(\n                    entityType.DisplayName(), entityType.BaseType.DisplayName()));\n        }\n    }\n\n    /// <summary>\n    ///     Validates a single sequence.\n    /// </summary>\n    /// <param name=\"sequence\">The sequence to validate.</param>\n    /// <param name=\"logger\">The logger to use.</param>\n    protected virtual void ValidateSequence(\n        ISequence sequence,\n        IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)\n    {\n    }\n\n    /// <summary>\n    ///     Validates a single database function.","sourceCodeStart":318,"sourceCodeEnd":354,"githubUrl":"https://github.com/dotnet/efcore/blob/dbf9771522148d61a2467854921bd5dc6f6e6916/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs#L318-L354","documentation":"ValidateSqlQuery (RelationalModelValidator.cs:332-339) throws when an entity type that has a base type (is derived) is mapped to a SQL query (ToSqlQuery/defining query) whose definition differs from its base type's, or when the derived type has no discriminator. EF requires the whole hierarchy to read from the same SQL query, so a derived type mapping to its own SQL query is rejected.","triggerScenarios":"Calling ToSqlQuery(...) (or setting GetSqlQuery) on a derived entity type with a different SQL than the base, or removing the discriminator while mapping a derived type to SQL. Thrown at model validation.","commonSituations":"Inheritance hierarchies where each derived type tries to supply its own raw SQL; refactoring a keyless SQL-query mapping into a hierarchy; mixing TPT/TPC with SQL-query mappings.","solutions":["Define the SQL query only on the base/root entity type and let derived types share it (with a discriminator for TPH).","Ensure the derived type either has no SQL query (inherits the base's) or the same SQL query string as the base.","If each type needs distinct SQL, model them as separate entity types (no inheritance) or separate keyless entities."],"exampleFix":"// before - derived type mapped to its own SQL\nmodelBuilder.Entity<Person>().ToSqlQuery(\"SELECT * FROM People\");\nmodelBuilder.Entity<Employee>().ToSqlQuery(\"SELECT * FROM Employees\"); // throws\n\n// after - share the base SQL, discriminate by column\nmodelBuilder.Entity<Person>().ToSqlQuery(\"SELECT * FROM People\");\nmodelBuilder.Entity<Person>().HasDiscriminator(p => p.Type);\n// do not call ToSqlQuery on Employee; it inherits the base query","handlingStrategy":"validation","validationCode":"foreach (var et in context.Model.GetEntityTypes())\n{\n    if (et.GetSqlQuery() != null && et.BaseType != null)\n    {\n        var baseQuery = et.BaseType.GetSqlQuery();\n        if (et.FindDiscriminatorProperty() == null || et.GetSqlQuery() != baseQuery)\n        {\n            // will throw - map SQL query only on the base and share it.\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Map ToSqlQuery() only on the hierarchy root; derived types inherit it.","Keep a discriminator when using SQL-query mapping in a hierarchy.","For per-type SQL, model separate non-inherited keyless entities."],"tags":["sql-query","inheritance","discriminator","model-validation"],"analyzedSha":"dbf9771522148d61a2467854921bd5dc6f6e6916","analyzedAt":"2026-08-06T20:46:03.226Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}