Ho una colonna varchar(max)
nullable in SQL Server che sto mappando a un Guid?
in codice EF prima. Tuttavia, questa proprietà è in realtà in una classe base derivata da molte altre entità.
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Model1>().Property(e => e.Property1).HasConversion(p => p.ToString(), p => (Guid?)Guid.Parse(p));
}
La riga sopra è ripetuta molte volte per ogni tabella. C'è un modo per dire a EF che questa è una proprietà di classe base, quindi la mappatura può essere dichiarata una sola volta?
Certo è possibile. Con la mancanza di convenzioni personalizzate, si ottiene con il ciclo "tipico" modelBuilder.Model.GetEntityTypes()
. Qualcosa di simile (basta cambiare la classe base e i nomi delle proprietà):
var entityTypes = modelBuilder.Model.GetEntityTypes()
.Where(t => t.ClrType.IsSubclassOf(typeof(BaseClass)));
var valueConverter = new ValueConverter<Guid, string>(
v => v.ToString(), v => (Guid?)Guid.Parse(v));
foreach (var entityType in entityTypes)
entityType.FindProperty(nameof(BaseClass.Property1)).SetValueConverter(valueConverter);
Si può anche prendere in considerazione l'utilizzo dell'EF Core fornito dal convertitore Guid
to String
:
var valueConverter = new GuidToStringConverter();
Un altro modo per fare è avere una classe di base corrispondente IEntityTypeConfiguration
:
internal class EntityConfiguration<T> : IEntityTypeConfiguration<T> where T : Entity
{
public virtual void Configure(EntityTypeBuilder<T> builder)
{
builder.Property(e => e.Property1).HasConversion(p => p.ToString(), p => (Guid?)Guid.Parse(p));
// ... Other base-specific config here
}
}
(Supponendo che qui la tua classe base sia chiamata Entity
- cambia se necessario).
Funziona meglio quando si utilizza il modello di factoring delle configurazioni dell'entità, quindi il tuo potrebbe essere così:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ApplyConfiguration(new Model1EntityConfiguration());
modelBuilder.ApplyConfiguration(new Model2EntityConfiguration());
// ...
}
...
internal sealed class Model1EntityConfiguration : EntityConfiguration<Model1>
{
public override void Configure(EntityTypeBuilder<Model1> builder)
{
base.Configure(builder); // <-- here's the key bit
// ...; e.g.
builder.Property(c => c.Name).HasMaxLength(80).IsRequired();
}
}