dotnet/efcore · error · InvalidOperationException

The function '{function}' has a custom translation. A compil

Error message

The function '{function}' has a custom translation. A compiled model cannot be generated because custom function translations are not supported.

What it means

Thrown by RelationalCSharpRuntimeAnnotationCodeGenerator when building a compiled model if a DbFunction has a custom Translation delegate (function.Translation != null). Custom translations are runtime delegates that cannot be serialized into the precompiled C# model, so compiled-model generation is blocked.

Source

Thrown at src/EFCore.Relational/Design/Internal/RelationalCSharpRuntimeAnnotationCodeGenerator.cs:1832

                    .Append(tableVariable).Append($".AddRowInternalForeignKey({structuralTypeVariable}, ")
                    .AppendLine("RelationalModel.GetForeignKey(this,").IncrementIndent()
                    .AppendLine($"{code.Literal(internalForeignKey.DeclaringEntityType.Name)},")
                    .AppendLine($"{code.Literal(internalForeignKey.Properties.Select(p => p.Name).ToArray())},")
                    .AppendLine($"{code.Literal(internalForeignKey.PrincipalEntityType.Name)},")
                    .AppendLine($"{code.Literal(internalForeignKey.PrincipalKey.Properties.Select(p => p.Name).ToArray())}));")
                    .DecrementIndent();
            }
        }
    }

    private void Create(
        IDbFunction function,
        string functionsVariable,
        CSharpRuntimeAnnotationCodeGeneratorParameters parameters)
    {
        if (function.Translation != null)
        {
            throw new InvalidOperationException(RelationalStrings.CompiledModelFunctionTranslation(function.Name));
        }

        AddNamespace(function.ReturnType, parameters.Namespaces);

        var code = Dependencies.CSharpHelper;
        var functionVariable = code.Identifier(
            function.MethodInfo?.Name ?? function.Name, function, parameters.ScopeObjects, capitalize: false);
        var mainBuilder = parameters.MainBuilder;
        mainBuilder
            .Append("var ").Append(functionVariable).AppendLine(" = new RuntimeDbFunction(").IncrementIndent()
            .Append(code.Literal(function.ModelName)).AppendLine(",")
            .Append(parameters.TargetName).AppendLine(",")
            .Append(code.Literal(function.ReturnType)).AppendLine(",")
            .Append(code.Literal(function.Name));

        if (function.Schema != null)
        {
            mainBuilder.AppendLine(",")

View on GitHub (pinned to dbf9771522)

Solutions

  1. Remove the custom translation for the function (drop HasTranslation / the Translation delegate) before generating a compiled model.
  2. Map the function via a store function or built-in translation that the compiled model can serialize.
  3. Skip compiled-model generation for this context and rely on the runtime model.
  4. If the translation is essential, keep it but do not enable compiled models.

Example fix

// before
modelBuilder.HasDbFunction(typeof(MyContext).GetMethod(nameof(MyUdf))!)
    .HasTranslation(args => /* custom SqlExpression */);
// dotnet ef dbcontext optimize  -> throws

// after (remove custom translation to allow compiled model)
modelBuilder.HasDbFunction(typeof(MyContext).GetMethod(nameof(MyUdf))!);
// map via schema/store name instead
Defensive patterns

Strategy: validation

Validate before calling

// Before compiled-model generation, check for custom translations
var hasCustom = context.Model.GetDbFunctions().Any(f => f.Translation != null);
if (hasCustom)
    throw new InvalidOperationException(
        "Remove HasTranslation/Translation delegates before compiling the model.");

Type guard

static bool HasCustomTranslations(IModel model)
    => model.GetDbFunctions().Any(f => f.Translation is not null);

Prevention

When it happens

Trigger: Running 'dotnet ef dbcontext optimize' / DesignTimeService compiled-model generation for a context that registers a DbFunction with HasTranslation(...) or a custom IDbMethodTranslator producing a Translation delegate (RelationalCSharpRuntimeAnnotationCodeGenerator.cs:1830-1832).

Common situations: Registering user-defined function mappings with custom SQL translation; using HasTranslation for complex DB function mappings; then enabling compiled models for startup performance.

Related errors


AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06). Data as JSON: /api/errors/a4fbb4464ef8a2f8. Report an issue: GitHub.