Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ConfigureSmartEnum not working #554

Open
ghost opened this issue Nov 7, 2024 · 5 comments
Open

ConfigureSmartEnum not working #554

ghost opened this issue Nov 7, 2024 · 5 comments

Comments

@ghost
Copy link

ghost commented Nov 7, 2024

this is my ConfigureConventions
image

The smart enum
image

How I use it under entity
image

The exception 'No suitable constructor was found for entity type 'UnitMaterial'. The following constructors had parameters that could not be bound to properties of the entity type: Cannot bind 'name', 'value' in 'UnitMaterial(string name, int value)'

how can I fix this ? please help
UnitMaterial and Entity is under my DOMAIN project, and dbContext is under INFRASTRUCTURE project

My specs
.NET 8.0
SmartEnum 8.1
SmartEnum.EFCore 8.1

@HAOYI99
Copy link

HAOYI99 commented Nov 21, 2024

can someone please help on this

@ardalis
Copy link
Owner

ardalis commented Nov 21, 2024

It looks right as is - if you create a minimal repo I can take a look.

As a workaround you can try this:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<YourEntity>()
        .Property(e => e.Unit)
        .HasConversion(
            v => v.Value, // Convert `SmartEnum` to its `value` (int)
            v => UnitMaterial.FromValue(v) // Convert `value` (int) back to `SmartEnum`
        );
}

@HAOYI99
Copy link

HAOYI99 commented Nov 22, 2024

It looks right as is - if you create a minimal repo I can take a look.

As a workaround you can try this:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<YourEntity>()
        .Property(e => e.Unit)
        .HasConversion(
            v => v.Value, // Convert `SmartEnum` to its `value` (int)
            v => UnitMaterial.FromValue(v) // Convert `value` (int) back to `SmartEnum`
        );
}

Hi @ardalis, thanks for the reply.

yes, I did use this method to manual map the conversion for each SmartEnum.

However, the document mentioned ConfigureSmartEnum is sufficient for configuring all SmartEnum.

I tried many times, ends up I create a SmartEnumConverter myself.

public class SmartEnumConverter<TEnum>() : ValueConverter<TEnum, string>(
    enumValue => enumValue.Name,
    stringValue => SmartEnum<TEnum, int>.FromName(stringValue, true)
) where TEnum : SmartEnum<TEnum, int>;

and the builder.ConfigureSmartEnum(); is not required with this approach

public static void ConfigureSmartEnum<TEnum>(this ModelConfigurationBuilder builder) where TEnum : SmartEnum<TEnum, int>
{
     builder.Properties<TEnum>().HaveConversion<SmartEnumConverter<TEnum>>();
}
protected override void ConfigureConventions(ModelConfigurationBuilder builder)
{
    base.ConfigureConventions(builder);
    builder.Properties<DateOnly>().HaveConversion<DateOnlyConverter>().HaveColumnType("date");
    builder.Properties<DateTime>().HaveColumnType("datetime");
    builder.Properties<TimeSpan>().HaveConversion<long>();
    builder.Properties<Enum>().HaveConversion<string>();
    builder.ConfigureSmartEnum<UnitMaterial>();
    builder.ConfigureSmartEnum<AmTechnologies>();
}

@bengavin
Copy link

bengavin commented Nov 22, 2024

We are running into this same error when generating migrations since moving to .NET 9. Any entity that has changed since the previous migration and contains a smart enum generates this exception during the migration generation process, unless the workaround given by @ardalis is used in the entity configuration.

I should note that this doesn't seem to effect runtime operation at all, it only seems to be required during the migration generation process if that helps troubleshooting at all.

@ardalis
Copy link
Owner

ardalis commented Nov 22, 2024

Yeah EF Core must have changed something in v9 I guess. We'll take a look and figure out how to do a more general solution (again) as soon as we can. Community assistance appreciated as always, including reproductions of the problem in clean repos so if we come up with a fix we can test it with your scenario.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants