{"record":{"id":"bff5dd2f20ee7cb6","repo":"dotnet/efcore","slug":"the-dbfunction-function-has-an-invalid-return","errorCode":null,"errorMessage":"The DbFunction '{function}' has an invalid return type '{type}'. Ensure that the return type can be mapped by the current provider.","messagePattern":"The DbFunction '(.+?)' has an invalid return type '(.+?)'\\. Ensure that the return type can be mapped by the current provider\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs","lineNumber":367,"sourceCode":"        IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)\n    {\n    }\n\n    /// <summary>\n    ///     Validates a single database function.\n    /// </summary>\n    /// <param name=\"dbFunction\">The database function to validate.</param>\n    /// <param name=\"logger\">The logger to use.</param>\n    protected virtual void ValidateDbFunction(\n        IDbFunction dbFunction,\n        IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)\n    {\n        var model = dbFunction.Model;\n        if (dbFunction.IsScalar)\n        {\n            if (dbFunction.TypeMapping == null)\n            {\n                throw new InvalidOperationException(\n                    RelationalStrings.DbFunctionInvalidReturnType(\n                        dbFunction.ModelName,\n                        dbFunction.ReturnType.ShortDisplayName()));\n            }\n        }\n        else\n        {\n            var elementType = dbFunction.ReturnType.GetGenericArguments()[0];\n            var entityType = model.FindEntityType(elementType);\n\n            if (entityType?.IsOwned() == true\n                || ((IConventionModel)model).IsOwned(elementType)\n                || (entityType == null && model.GetEntityTypes().Any(e => e.ClrType == elementType)))\n            {\n                throw new InvalidOperationException(\n                    RelationalStrings.DbFunctionInvalidIQueryableOwnedReturnType(\n                        dbFunction.ModelName, elementType.ShortDisplayName()));\n            }","sourceCodeStart":349,"sourceCodeEnd":385,"githubUrl":"https://github.com/dotnet/efcore/blob/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs#L349-L385","documentation":"ValidateDbFunction throws DbFunctionInvalidReturnType when a scalar DbFunction has no resolved type mapping (dbFunction.TypeMapping == null). The provider could not map the function's return type to a store type, meaning the CLR return type is unsupported by the current provider. Distinct from the IQueryable-return variant (359) which targets owned-entity returns.","triggerScenarios":"Registering HasDbFunction for a method whose return CLR type has no relational type mapping — e.g. a custom struct, an unsupported primitive, or a type whose mapping requires a value converter not configured for DbFunction resolution. Only fires when dbFunction.IsScalar and TypeMapping is null.","commonSituations":"Using a provider-specific function returning a type the provider doesn't map by default (e.g. timespan, char, decimal with unusual scale); registering a DbFunction whose return type is a domain enum without configuring the enum conversion; upgrading the provider and losing a previously-inferred mapping.","solutions":["Change the DbFunction's return type to one the provider maps natively (int, string, DateTime, double, etc.).","Register a value converter / type mapping for the custom return type before defining the DbFunction.","If wrapping a database function returning an exotic type, expose it through a SQL view or compute a primitive in the method body."],"exampleFix":"// before — MoneyAmount is a custom struct with no mapping\npublic static MoneyAmount Total(this DbContext db, int id)\n    => throw new NotImplementedException();\nmodelBuilder.HasDbFunction(typeof(MyCtx).GetMethod(nameof(MyCtx.Total))!); // throws\n\n// after — return decimal, convert at the call site\npublic static decimal Total(this DbContext db, int id)\n    => throw new NotImplementedException();","handlingStrategy":"validation","validationCode":"if (dbFunction.IsScalar && dbFunction.TypeMapping is null)\n    throw new InvalidOperationException($\"DbFunction {dbFunction.ModelName} return type {dbFunction.ReturnType} has no mapping.\");","typeGuard":"static bool HasScalarMapping(IDbFunction f)\n    => !f.IsScalar || f.TypeMapping is not null;","tryCatchPattern":null,"preventionTips":["Use provider-mappable return types for scalar DbFunctions (int, string, DateTime, double).","Register value converters / mappings for custom return types before HasDbFunction.","Validate DbFunction return types in a model-finalization unit test."],"tags":["dbfunction","type-mapping","scalar-function","model-validation"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}