dotnet/efcore · error · InvalidOperationException

The property ' . ' has a value generator configured. Use '…

Error message

The property '{entityType}.{property}' has a value generator configured. Use '{method}' to configure the value generator factory type.

What it means

Thrown by CSharpRuntimeModelCodeGenerator when a property has a value generator instance configured (GetValueGeneratorFactory() is non-null) but no ValueGeneratorFactoryType annotation. Compiled models can only persist a factory type (so it can be reconstructed), not an arbitrary generator instance, so an instance-only configuration is refused; the message directs you to use HasValueGeneratorFactory instead.

Solutions

  1. Switch from HasValueGenerator<TInstance>() to HasValueGeneratorFactory<TFactory>() so the compiled model can store the type.
  2. Provide a ValueGenerator factory type that the compiled model can serialize.
  3. If an instance is truly required, accept that the compiled model cannot encode it and configure it at runtime.

Example fix

// before
modelBuilder.Entity<E>().Property(p => p.Id).HasValueGenerator<MyGenerator>();
// after
modelBuilder.Entity<E>().Property(p => p.Id).HasValueGeneratorFactory<MyGeneratorFactory>();
Defensive patterns

Strategy: validation

Validate before calling

// Detect instance-based value generators before compiled-model generation
foreach (var p in model.GetEntityTypes().SelectMany(e => e.GetProperties()))
{
    var factoryType = (Type?)p[CoreAnnotationNames.ValueGeneratorFactoryType];
    if (factoryType is null && p.GetValueGeneratorFactory() is not null)
        Console.WriteLine($"{p.DeclaringType}.{p.Name} uses an instance generator; switch to HasValueGeneratorFactory.");
}

Try / catch

try { Optimize(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("value generator"))
{ /* switch to HasValueGeneratorFactory<TFactory> then regenerate */ }

Prevention

When it happens

Trigger: Configuring a property with HasValueGenerator(...) (an instance) rather than HasValueGeneratorFactory(...) (a type), then generating a compiled model.

Common situations: Custom value generators registered as instances; migrating value-generator configuration to the compiled-model workflow.

Related errors


AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11). Data as JSON: /api/errors/6d30b499347db8fb. Report an issue: GitHub.

Appendix: source

Thrown at src/EFCore.Design/Scaffolding/Internal/CSharpRuntimeModelCodeGenerator.cs:1088

                    .Append(_code.UnknownLiteral(providerValue))
                    .AppendLine(");")
                    .AppendLine();
            }
        }
    }

    private void Create(
        IProperty property,
        Dictionary<MemberInfo, QualifiedName>? memberAccessReplacements,
        CSharpRuntimeAnnotationCodeGeneratorParameters parameters)
    {
        var variableName = _code.Identifier(property.Name, property, parameters.ScopeObjects, capitalize: false);

        var valueGeneratorFactoryType = (Type?)property[CoreAnnotationNames.ValueGeneratorFactoryType];
        if (valueGeneratorFactoryType == null
            && property.GetValueGeneratorFactory() != null)
        {
            throw new InvalidOperationException(
                DesignStrings.CompiledModelValueGenerator(
                    property.DeclaringType.ShortName(), property.Name, nameof(PropertyBuilder.HasValueGeneratorFactory)));
        }

        var mainBuilder = parameters.MainBuilder;
        mainBuilder
            .Append("var ").Append(variableName).Append(" = ").Append(parameters.TargetName).AppendLine(".AddProperty(")
            .IncrementIndent()
            .Append(_code.Literal(property.Name));

        GeneratePropertyBaseParameters(property, parameters);

        if (property.IsNullable)
        {
            mainBuilder.AppendLine(",")
                .Append("nullable: ")
                .Append(_code.Literal(true));
        }

View on GitHub (pinned to 3a2006ef56)