web-dev-qa-db-fra.com

Passer d'EF6 à EF Core 2.0

Je viens de commencer à déplacer mon projet MVC5 avec EF6x vers MVC Core et EF Core, mais j'ai un gros problème avec la configuration de mes entités. Comment migrer une configuration EF6 Fluent vers EF core?
J'ai besoin d'un guide avec un échantillon si possible.

Voici une de mes classes de cartographie et mon essai

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);
        }
    }

ancienne configuration simple

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);
    }
}

Mon essai

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);
    }

}

Je l'ai fait en utilisant la recherche Google et la documentation Microsoft. Mais je ne suis pas sûr de mon travail. Puisque j'ai +100 classes de configuration, je vais vous demander avant de continuer. Je m'excuse si le contenu de ma question n'est pas compatible avec les termes et conditions du site.

12
CS-Beginner

J'ai trouvé un bon article sur le passage au noyau EF. Je veux partager cela et garder cette question pour des débutants comme moi.

Mises à jour du code
Espace de noms System.Data.Entity Remplacé par Microsoft.EntityFrameworkCore
HasDatabaseGeneratedOption(DatabaseGeneratedOption.None) remplacé par ValueGeneratedNever();
Le constructeur de base de DbContext n'a pas de paramètre de chaîne unique pour la chaîne de connexion. Nous devons maintenant injecter le DbContextOptions
OnModelCreating(DbModelBuilder modelBuilder) devient OnModelCreating(ModelBuilder modelBuilder). Changement simple, mais change tout de même
modelBuilder.Configurations.AddFromAssembly(Assembly.GetExecutingAssembly()); n'est plus disponible, ce qui signifie que EntityTypeConfiguration n'est pas non plus disponible, j'ai donc dû déplacer toute ma configuration d'entité vers OnModelCreating
((IObjectContextAdapter)context).ObjectContext.ObjectMaterialized N'est plus disponible. J'utilisais cela pour étendre le DbContext pour convertir toutes les dates d'une sortie en Utc. Je n'ai pas encore trouvé de remplaçant pour ça.
ComplexType n'est plus disponible. J'ai dû changer un peu la structure du modèle pour s'adapter à cela.
MigrateDatabaseToLatestVersion n'est plus disponible, j'ai donc dû ajouter ce qui suit à mon startup.cs

using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
    serviceScope.ServiceProvider.GetService<SbDbContext>().Database.Migrate();
}

WillCascadeOnDelete(false) devient OnDelete(DeleteBehavior.Restrict)
HasOptional n'est plus pertinent selon l'article
IDbSet devient DbSet
DbSet<T>.Add() ne renvoie plus T mais 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<>) renvoie maintenant IIncludableQueryable<T,Y> au lieu de IQueryable<T>, il en va de même pour OrderBy. Ce que j'ai fait, c'est déplacer tous les inclusions et commandes à la fin.

Source: Passer d'EF6 à EF Core

17
CS-Beginner