{"record":{"id":"a4fbb4464ef8a2f8","repo":"dotnet/efcore","slug":"the-function-function-has-a-custom-translation","errorCode":null,"errorMessage":"The function '{function}' has a custom translation. A compiled model cannot be generated because custom function translations are not supported.","messagePattern":"The function '(.+?)' has a custom translation\\. A compiled model cannot be generated because custom function translations are not supported\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Design/Internal/RelationalCSharpRuntimeAnnotationCodeGenerator.cs","lineNumber":1832,"sourceCode":"                    .Append(tableVariable).Append($\".AddRowInternalForeignKey({structuralTypeVariable}, \")\n                    .AppendLine(\"RelationalModel.GetForeignKey(this,\").IncrementIndent()\n                    .AppendLine($\"{code.Literal(internalForeignKey.DeclaringEntityType.Name)},\")\n                    .AppendLine($\"{code.Literal(internalForeignKey.Properties.Select(p => p.Name).ToArray())},\")\n                    .AppendLine($\"{code.Literal(internalForeignKey.PrincipalEntityType.Name)},\")\n                    .AppendLine($\"{code.Literal(internalForeignKey.PrincipalKey.Properties.Select(p => p.Name).ToArray())}));\")\n                    .DecrementIndent();\n            }\n        }\n    }\n\n    private void Create(\n        IDbFunction function,\n        string functionsVariable,\n        CSharpRuntimeAnnotationCodeGeneratorParameters parameters)\n    {\n        if (function.Translation != null)\n        {\n            throw new InvalidOperationException(RelationalStrings.CompiledModelFunctionTranslation(function.Name));\n        }\n\n        AddNamespace(function.ReturnType, parameters.Namespaces);\n\n        var code = Dependencies.CSharpHelper;\n        var functionVariable = code.Identifier(\n            function.MethodInfo?.Name ?? function.Name, function, parameters.ScopeObjects, capitalize: false);\n        var mainBuilder = parameters.MainBuilder;\n        mainBuilder\n            .Append(\"var \").Append(functionVariable).AppendLine(\" = new RuntimeDbFunction(\").IncrementIndent()\n            .Append(code.Literal(function.ModelName)).AppendLine(\",\")\n            .Append(parameters.TargetName).AppendLine(\",\")\n            .Append(code.Literal(function.ReturnType)).AppendLine(\",\")\n            .Append(code.Literal(function.Name));\n\n        if (function.Schema != null)\n        {\n            mainBuilder.AppendLine(\",\")","sourceCodeStart":1814,"sourceCodeEnd":1850,"githubUrl":"https://github.com/dotnet/efcore/blob/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Relational/Design/Internal/RelationalCSharpRuntimeAnnotationCodeGenerator.cs#L1814-L1850","documentation":"Thrown by RelationalCSharpRuntimeAnnotationCodeGenerator when generating a compiled model if a DbFunction has a custom Translation delegate (function.Translation != null). Compiled models serialize the model into generated C#; arbitrary translation delegates (method references to user code) cannot be serialized into the compiled model, so the build is blocked.","triggerScenarios":"Running 'dotnet ef dbcontext optimize' / compiled-model generation while a DbFunction is registered with HasTranslation(...) providing a custom SQL translation delegate.","commonSituations":"A model uses modelBuilder.HasDbFunction(...).HasTranslation(t => ...) to translate a CLR method to custom SQL, and the project then opts into compiled models for startup performance.","solutions":["Remove the custom HasTranslation delegate and rely on a database-side function / default translation when using compiled models.","Keep the compiled model but exclude/opt out for that context and run without compilation.","Move the custom translation into a provider extension or a SQL UDF instead of a runtime delegate."],"exampleFix":"// before\nmodelBuilder.HasDbFunction(typeof(MyFunctions).GetMethod(nameof(MyFunctions.MyCustom))!)\n    .HasTranslation(args => new SqlFunctionExpression(...)); // blocks compiled model\n// dotnet ef dbcontext optimize -> throws\n\n// after: map to a database function instead\nmodelBuilder.HasDbFunction(typeof(MyFunctions).GetMethod(nameof(MyFunctions.MyCustom))!)\n    .HasName(\"my_custom\");","handlingStrategy":"validation","validationCode":"// Before generating a compiled model, ensure no DbFunction has a custom translation\nforeach (var fn in modelBuilder.Model.GetDbFunctions())\n{\n    if (fn.Translation != null)\n        throw new InvalidOperationException($\"DbFunction {fn.Name} has a custom translation; remove HasTranslation before compiling the model.\");\n}\n// dotnet ef dbcontext optimize","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Avoid HasTranslation delegates if you plan to use compiled models.","Map DbFunctions to database UDFs instead of runtime translation delegates.","Run a pre-build check that scans GetDbFunctions() for non-null Translation."],"tags":["ef-core","compiled-model","dbfunction","design-time","relational"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}