Support `HasConversion` to primitive collection types
- Dominant language
- C#
- Stars
- 14.8k
- Forks
- 3.4k
- PR merge metrics
- PR metrics pending
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();` 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](https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-8.0/whatsnew#primitive-collections) and we are going to be able to simply use `.HasConversion();` but no luck.
### Example
**Entity**
```C#
public class Rider
{
public Guid Id { get; set; }
public List 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**
```C#
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();
}
else
{
modelBuilder
.Entity(entityType.ClrType)
.Property(enumProperty.Name)
.HasConversion();
}
}
}
}
```
### 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(type: "uuid", nullable: false),
mount = table.Column(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
Contributor guide
Assessment
This issue has not been assessed yet.