dotnet/efcore · error · InvalidOperationException

The property '{entityType}.{property}' has a value generator

Error message

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

What it means

Thrown in CSharpRuntimeModelCodeGenerator.Create(IProperty) (line 1088, resource CompiledModelValueGenerator) when generating a compiled model for a property that has a value generator configured via a factory instance rather than a factory type. Compiled models can only encode a value-generator factory type, so when a property has GetValueGeneratorFactory() != null but no ValueGeneratorFactoryType annotation, generation aborts and points you to HasValueGeneratorFactory.

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 dbf9771522)

Solutions

  1. Replace HasValueGenerator(instance factory) with HasValueGeneratorFactory(typeof(MyGenerator)) so the compiled model can encode the type.
  2. Ensure your value generator has a parameterless constructor so it can be activated from the factory type.
  3. Re-run compiled-model generation after the switch.
  4. If an instance factory is mandatory, exclude the property/entity from compiled-model generation.

Example fix

// before: instance-based value generator blocks compiled models
modelBuilder.Entity<Order>()
    .Property(o => o.Number)
    .HasValueGenerator(() => new OrderNumberGenerator());

// after: type-based factory the compiled model can encode
modelBuilder.Entity<Order>()
    .Property(o => o.Number)
    .HasValueGeneratorFactory<OrderNumberGenerator>();
Defensive patterns

Strategy: validation

Validate before calling

// Detect instance-based value generators before compiled-model generation
foreach (var et in model.GetEntityTypes())
foreach (var p in et.GetProperties())
    if (p[CoreAnnotationNames.ValueGeneratorFactoryType] is null
        && p.GetValueGeneratorFactory() is not null)
    { /* switch to HasValueGeneratorFactory<T>() */ }

Try / catch

try { /* generate compiled model */ }
catch (InvalidOperationException ex) when (ex.Message.Contains("value generator"))
{ /* switch HasValueGenerator -> HasValueGeneratorFactory<T>(), then retry */ }

Prevention

When it happens

Trigger: Running compiled-model generation for a property configured with HasValueGenerator (an instance-based factory) rather than HasValueGeneratorFactory (a type-based factory). The check `valueGeneratorFactoryType == null && property.GetValueGeneratorFactory() != null` is true and throws CompiledModelValueGenerator(entityType, property, nameof(PropertyBuilder.HasValueGeneratorFactory)).

Common situations: Configuring a property with HasValueGenerator(() => new MyGenerator()) and then enabling compiled models. Instance-based generators cannot be serialized into the compiled model source. Switching an existing model to compiled models reveals these instance-based configurations.

Related errors


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