Laraue.EfCoreTriggers icon indicating copy to clipboard operation
Laraue.EfCoreTriggers copied to clipboard

Enum fields with string conversion are not working

Open myllete opened this issue 2 years ago • 5 comments

Hi,

If i have an enum:

public enum ServiceStatus
{
  NotActive,
  Active 
}

and classes Service and ServiceHistory:

public class Service
{
  public ServiceStatus Status { get; set; }
}

public class ServiceHistory
{
  public ServiceStatus OldStatus { get; set; }
  public ServiceStatus NewStatus { get; set; }
}

with:

builder.Entity<Service>().Property(s => s.Status).HasColumnType("varchar(100)").HasConversion<string>();
builder.Entity<ServiceHistory>().Property(s => s.Status).HasColumnType("varchar(100)").HasConversion<string>();

then

builder.Entity<Service>().AfterUpdate(trigger =>
  trigger.Action(action => action.Insert((sold, snew) => new ServiceHistory { OldStatus = sold.Status, NewStatus = snew.Status })))

generates TRIGGER with

... @OldStatus INT ... @NewStatus INT

and then when updating Service "Conversion failed when converting the varchar value 'NotActive' to data type int." is thrown.

myllete avatar May 18 '22 10:05 myllete

It seams that you got the configuration of HasConvertion() wrong.

According to this link you should do something like: builder.Entity<Service>().Property(s => s.Status).HasColumnType("varchar(100)").HasConversion( v => v.ToString(), v => (ServiceStatus)Enum.Parse(typeof(ServiceStatus), v));

MacyF avatar Jul 07 '22 13:07 MacyF

It seams that you got the configuration of HasConvertion() wrong.

According to this link you should do something like: builder.Entity<Service>().Property(s => s.Status).HasColumnType("varchar(100)").HasConversion( v => v.ToString(), v => (ServiceStatus)Enum.Parse(typeof(ServiceStatus), v));

If you open that link and scroll to "Pre-defined conversions", you'll find that

"EF Core contains many pre-defined conversions that avoid the need to write conversion functions manually. Instead, EF Core will pick the conversion to use based on the property type in the model and the requested database provider type.

For example, enum to string conversions are used as an example above, but EF Core will actually do this automatically when the provider type is configured as string using the generic type of HasConversion

That conversion works otherwise just fine as it should. If you have tested that the triggers are created correctly if conversion is done manually then thanks, I'll check that out, but even in that case it should be working with pre-defined conversions (or at least documentation should be updated in regards of that).

myllete avatar Jul 07 '22 14:07 myllete

I wasn't aware of pre-defined conversions and either tested if my suggestion works 😅 I thought that probably that was the problem, since it was complaining about the conversion.

MacyF avatar Jul 07 '22 16:07 MacyF

I just released versions 5.4.0-alpha and 6.4.0-alpha with support of string enum values. Please, check it.

win7user10 avatar Jul 16 '22 14:07 win7user10

I just released versions 5.4.0-alpha and 6.4.0-alpha with support of string enum values. Please, check it.

It seems that SqlServer trigger is still created with INTs (using 6.4.0-alpha from nuget.org).

myllete avatar Jul 18 '22 07:07 myllete

Fixed in 5.4.1/6.4.1

win7user10 avatar Oct 29 '22 10:10 win7user10