-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Description
Description
In the Entities we use Enum types a lot and we make sure to store them as strings instead of numbers
For this we use .HasConversion<string>();
and it works great.
Now we would like to also support collections of Enums and have them serialized as text[] for consistency
And you would think this is a job for EF Core 8 Primitive Collections and we are going to be able to simply use .HasConversion<string[]>();
but no luck.
Example
Entity
public class Rider
{
public Guid Id { get; set; }
public List<EquineBeast> Mounts { get; set; }
}
public enum EquineBeast
{
Donkey,
Mule,
Horse,
Unicorn
}
I will include the full code because we configure all Enum based entities at once
OnModelCreating
private void SaveEnumAsString(ModelBuilder modelBuilder)
{
var entityTypes = modelBuilder.Model.GetEntityTypes();
foreach (var entityType in entityTypes)
{
var enumProperties = entityType.ClrType.GetProperties()
.Where(p => p.PropertyType.IsEnum
|| (p.PropertyType.IsGenericType
&& p.PropertyType.GetGenericTypeDefinition() == typeof(List<>)
&& p.PropertyType.GetGenericArguments()[0].IsEnum));
foreach (var enumProperty in enumProperties)
{
if(enumProperty.PropertyType.IsEnum)
{
modelBuilder
.Entity(entityType.ClrType)
.Property(enumProperty.Name)
.HasConversion<string>();
}
else
{
modelBuilder
.Entity(entityType.ClrType)
.Property(enumProperty.Name)
.HasConversion<string[]>();
}
}
}
}
Problem
Now here is the odd part.
When we create the migration EF Core is stuck with int[]
migrationBuilder.CreateTable(
name: "riders",
columns: table => new
{
id = table.Column<Guid>(type: "uuid", nullable: false),
mount = table.Column<int[]>(type: "integer[]", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("pk_riders", x => x.id);
});
We can force the column type with .HasColumnType("text[]")
but it is creating more problems down the path.
Namely the migration will apply but at runtime fails to load/convert the field
Exception has occurred: CLR/System.InvalidCastException
Exception thrown: 'System.InvalidCastException' in Microsoft.EntityFrameworkCore.Relational.dll: 'Reading as 'System.Int32[]' is not supported for fields having DataTypeName 'text[]''
Version information
EF Core version: Microsoft.EntityFrameworkCore.Design 8.0.0
Database provider: Npgsql.EntityFrameworkCore.PostgreSQL 8.0.0
Target framework: net8.0