labdb/Models/EntityBase.cs
2022-11-10 21:33:45 +01:00

63 lines
2.2 KiB
C#

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace labdb.Models;
public abstract class EntityBase<TId>
where TId : EntityIdBase<TId>, new()
{
// ReSharper disable once AutoPropertyCanBeMadeGetOnly.Local - EF Core needs a setter
public TId Id { get; private set; } = new();
}
public abstract class EntityBaseConfiguration<TEntity, TId> : IEntityTypeConfiguration<TEntity>
where TEntity : EntityBase<TId>
where TId : EntityIdBase<TId>, new()
{
public virtual void Configure(EntityTypeBuilder<TEntity> builder)
{
builder.HasKey(x => x.Id);
ApplyTypedIdConverters(builder);
ApplyEnumConverters(builder);
}
private void ApplyTypedIdConverters(EntityTypeBuilder<TEntity> builder)
{
foreach (var propertyInfo in typeof(TEntity).GetProperties()
.Where(x => x.PropertyType.IsAssignableTo(typeof(EntityIdBase))))
{
var idConverterType = typeof(EntityIdConverter<>).MakeGenericType(propertyInfo.PropertyType);
var idConverterConstructor = idConverterType.GetConstructor(Array.Empty<Type>());
var idConverter = (ValueConverter)idConverterConstructor!.Invoke(Array.Empty<object>());
builder.Property(propertyInfo.Name)
.HasConversion(idConverter);
}
}
private void ApplyEnumConverters(EntityTypeBuilder<TEntity> builder)
{
foreach (var propertyInfo in typeof(TEntity).GetProperties()
.Where(x => x.PropertyType.IsEnum))
{
var enumConverterType = typeof(EnumConverter<>).MakeGenericType(propertyInfo.PropertyType);
var enumConverterConstructor = enumConverterType.GetConstructor(Array.Empty<Type>());
var enumConverter = (ValueConverter)enumConverterConstructor!.Invoke(Array.Empty<object>());
builder.Property(propertyInfo.Name)
.HasConversion(enumConverter);
}
}
}
public class EnumConverter<TEnum> : ValueConverter<TEnum, string>
where TEnum : Enum
{
public EnumConverter() : base(
x => x.ToString(),
x => (TEnum)Enum.Parse(typeof(TEnum), x))
{
}
}