Ho appena iniziato a spostare il mio progetto MVC5 con EF6x su MVC Core ed EF Core, ma ho un grosso problema con la configurazione delle mie entità. In che modo è possibile migrare un EF6 Fluent configurato su EF core?
Ho bisogno di una guida con il campione, se possibile.
Ecco una delle mie lezioni di mappatura e il mio tentativo
EntityMappingConfiguratuin
public interface IEntityMappingConfiguration
{
void Map(ModelBuilder b);
}
public interface IEntityMappingConfiguration<T> : EntityMappingConfiguration where T : class
{
void Map(EntityTypeBuilder<T> builder);
}
public abstract class EntityMappingConfiguration<T> : EntityMappingConfiguration<T> where T : class
{
public abstract void Map(EntityTypeBuilder<T> b);
public void Map(ModelBuilder b)
{
Map(b.Entity<T>());
}
}
public static class ModelBuilderExtenions
{
private static IEnumerable<Type> GetMappingTypes(this Assembly assembly, Type mappingInterface)
{
return assembly.GetTypes().Where(x => !x.IsAbstract && x.GetInterfaces().Any(y => y.GetTypeInfo().IsGenericType && y.GetGenericTypeDefinition() == mappingInterface));
}
public static void AddEntityConfigurationsFromAssembly(this ModelBuilder modelBuilder, Assembly assembly)
{
var mappingTypes = assembly.GetMappingTypes(typeof(IEntityMappingConfiguration<>));
foreach (var config in mappingTypes.Select(Activator.CreateInstance).Cast<IEntityMappingConfiguration>())
{
config.Map(modelBuilder);
}
}
}
DbContext
public class CommerceServiceDbContext : AbpDbContext
{
public CommerceServiceDbContext(DbContextOptions<CommerceServiceDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.AddEntityConfigurationsFromAssembly(GetType().Assembly);
}
}
Semplice vecchia configurazione
public partial class AffiliateMap : EntityMappingConfiguration<Affiliate>
{
public override void Map(EntityTypeBuilder<Affiliate> b)
{
b.ToTable("Affiliate");
b.HasKey(a => a.Id);
b.HasRequired(a => a.Address).WithMany().HasForeignKey(x => x.AddressId).WillCascadeOnDelete(false);
}
}
La mia prova
public partial class AffiliateMap : EntityMappingConfiguration<Affiliate>
{
public override void Map(EntityTypeBuilder<Affiliate> b)
{
b.ToTable("Affiliate");
b.HasKey(a => a.Id);
b.HasOne(a => a.Address)
.WithMany().HasForeignKey(x => x.AddressId).IsRequired().OnDelete(DeleteBehavior.Restrict);
}
}
L'ho fatto usando Ricerca Google e Documentazione Microsoft. Ma non sono sicuro del mio lavoro. Dato che ho +100 configurazioni delle classi, ti chiederò prima di continuare. Mi scuso se i contenuti della mia domanda non sono compatibili con i termini e le condizioni del sito.
Ho trovato un buon articolo sul passaggio al core EF. Voglio condividere questo e mantenere questa domanda per i principianti come me.
Aggiornamenti del codice
Namespace System.Data.Entity
sostituito da Microsoft.EntityFrameworkCore
HasDatabaseGeneratedOption(DatabaseGeneratedOption.None)
sostituito da ValueGeneratedNever();
Il costruttore di base di DbContext
non ha un singolo parametro di stringa per la stringa di connessione. Ora dobbiamo iniettare DbContextOptions
OnModelCreating(DbModelBuilder modelBuilder)
diventa OnModelCreating(ModelBuilder modelBuilder)
. Cambiamento semplice, ma cambia tutto lo stesso
modelBuilder.Configurations.AddFromAssembly(Assembly.GetExecutingAssembly());
non è più disponibile, il che significa che EntityTypeConfiguration
non è disponibile, quindi ho dovuto spostare tutta la mia configurazione di entità in OnModelCreating
((IObjectContextAdapter)context).ObjectContext.ObjectMaterialized
non è più disponibile. Lo stavo usando per estendere DbContext
per convertire tutte le date in un out in Utc. Non ho ancora trovato un sostituto per questo.
ComplexType
non è più disponibile. Ho dovuto cambiare un po 'la struttura del modello per adattarlo.
MigrateDatabaseToLatestVersion
non è più disponibile quindi ho dovuto aggiungere il seguente al mio startup.cs
using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
serviceScope.ServiceProvider.GetService<SbDbContext>().Database.Migrate();
}
WillCascadeOnDelete(false)
diventa OnDelete(DeleteBehavior.Restrict)
HasOptional
non è più rilevante come per post
IDbSet
diventa DbSet
DbSet<T>.Add()
non restituisce più T
ma EntityEntry<T>
var entry = context.LearningAreaCategories.Add(new LearningAreaCategory());
//that's if you need to use the entity afterwards
var entity = entry.Entity;
IQueryable<T>.Include(Func<>)
ora restituisce IIncludableQueryable<T,Y>
invece di IQueryable<T>
, lo stesso vale per OrderBy
. Quello che ho fatto è stato spostare tutti gli include e orderbys fino alla fine.
Fonte: passaggio da EF6 a EF Core