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

EF Core 7 InMemory - Throwing System.ArgumentException with any query involving a SmartEnum #400

Open
jbaconCCG opened this issue May 23, 2023 · 3 comments

Comments

@jbaconCCG
Copy link

Upgrading my solution to .NET 7 and suddenly hitting the following exception when running unit tests:

System.ArgumentException : Expression of type 'Ardalis.SmartEnum.SmartEnum'2[Namespace.ReserveCostGroupEnum,System.String]' cannot be used for parameter of type 'System.String' of method 'Namespace.ReserveCostGroupEnum GetFromValue(System.String)' (Parameter 'arg0')

Unsure if the problem lies with the Microsoft.EntityFrameworkCore.InMemory package or SmartEnum.
I am not getting the issue running through SQL server, only through unit tests using an InMemory db.
Tried applying the Conversion through:

protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder)
        {
            configurationBuilder.ConfigureSmartEnum();
        }

and

builder.Property(p => p.ReserveCostGroup).HasColumnType("varchar(20)").HasConversion(p => p.Value, p => ReserveCostGroupEnum.FromValue(p));

I've upgraded all the SmartEnum packages to the newest available.
An example of a simple query that fails:

var enumTest = await dbContext.Test_Table.Where(q => q.ReserveCostGroup == ReserveCostGroupEnum.SubContractor).ToListAsync()

an example of the SmartEnum:

public sealed class ReserveCostGroupEnum : SmartEnum<ReserveCostGroupEnum, string>
    {
        public static readonly ReserveCostGroupEnum None = new ReserveCostGroupEnum(nameof(None), "None");
        public static readonly ReserveCostGroupEnum Buildings = new ReserveCostGroupEnum(nameof(Buildings), "Buildings");
        public static readonly ReserveCostGroupEnum Contents = new ReserveCostGroupEnum(nameof(Contents), "Contents");
        public static readonly ReserveCostGroupEnum Expenses = new ReserveCostGroupEnum(nameof(Expenses), "Expenses");
        public static readonly ReserveCostGroupEnum SubContractor = new ReserveCostGroupEnum(nameof(SubContractor), "SubContractor");
        public static readonly ReserveCostGroupEnum Costs = new ReserveCostGroupEnum(nameof(Costs), "Costs");
        public ReserveCostGroupEnum(string name, string value) : base(name, value)
        {
        }
    }

Any help would be greatly appreciated!

@ardalis
Copy link
Owner

ardalis commented May 23, 2023

Can you share what version(s) of EF Core and SmartEnum libraries you're on? I know you said latest but just confirming so I can reproduce with the same stuff you have. Thanks!

@jbaconCCG
Copy link
Author

Yeah no worries:

Ardalis.SmartEnum 7.0.0
Ardalis.SmartEnum.EFCore 7.0.0
Microsoft.EntityFrameworkCore 7.0.5
Microsoft.EntityFrameworkCore.InMemory 7.0.5

Thanks for taking a look!

@jbaconCCG
Copy link
Author

Dug into it a bit more today and the issue seems to only happen when checking for null using operators, it works fine when using '.Equals'.
i.e.:

            ClaimOutcomeEnum outcome = await dbContext.Table_Test
                    .Where(q => !q.ClaimOutcome.Equals(null))
                    .Select(t => t.ClaimOutcome)
                    .FirstOrDefaultAsync();

This works fine, however

            ClaimOutcomeEnum outcome = await dbContext.Table_Test
                    .Where(q => q.ClaimOutcome != null)
                    .Select(t => t.ClaimOutcome)
                    .FirstOrDefaultAsync();

bombs out with 'System.ArgumentException'. (sorry, I know this is different to my original example!)

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

2 participants