web-dev-qa-db-fra.com

Comment ajouter une implémentation de 'IDesignTimeDbContextFactory <DataContext>' au projet dans asp.net-core-2.0

Voici la liste des packages que j'ai installés: Packages installés

J'utilise Entityframework Core 2.0. Première fois que j'ai créé avec succès une base de données en utilisant la première migration du code de structure d'entité (commande add-migration et update-database) . Maintenant, lorsque je mets à jour mes entités et que j'essaie d'exécuter la migration, l'erreur suivante s'affiche.

Impossible de créer un objet de type 'DataContext'. Ajoutez une implémentation de 'IDesignTimeDbContextFactory' au projet ou consultez https://go.Microsoft.com/fwlink/?linkid=851728 pour connaître les modèles supplémentaires pris en charge à la conception. 

Voici mon code ... 

Program.cs

public static void Main(string[] args)
{
    BuildWebHost(args).Run();
}

public static IWebHost BuildWebHost(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .Build();

Startup.cs

public Startup(IConfiguration configuration)
{
    Configuration = configuration;
}

public IConfiguration Configuration { get; }

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    // Repositories

    services.AddMvc();
    services.AddDbContextPool<DataContext>(
        options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
        //options => options.UseSqlServer(@"Server=LAPTOP-518D8067;Database=Gyanstack;Trusted_Connection=True;MultipleActiveResultSets=true"));

    services.AddCors();
    services.AddScoped<ISectionRepository, SectionRepository>();
    services.AddScoped(typeof(IEntityBaseRepository<>), typeof(EntityBaseRepository<>));
}

DataContext.cs

public class DataContext : DbContext
{
    public DataContext(DbContextOptions<DataContext> options) 
        : base(options)
    { }

    public DbSet<Section> Section { get; set; }
    public DbSet<SubSection> SubSection { get; set; }
    public DbSet<Article> Article { get; set; }
    public DbSet<Comment> Comment { get; set; }
    public DbSet<User> User { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.AddConfiguration(new SectionMap());
        modelBuilder.AddConfiguration(new SubSectionMap());
        modelBuilder.AddConfiguration(new ArticleMap());
        modelBuilder.AddConfiguration(new CommentMap());
    }
}
16
M J

EDIT: maintenant obsolète. Microsoft a mis à jour son document de migration à la fin du mois de septembre pour montrer comment procéder à la mise à jour pour éviter cette solution de contournement.

Comme indiqué sur ce problème que j'ai soulevé sur github , vous déplacez votre code d'initialisation de base de données vers le programme principal, en le plaçant entre BuildWebHost () et .Run ()

C'est relativement facile une fois que vous avez compris que vous devez obtenir le contexte de la base de données en utilisant var context = services.GetRequiredService<MyContext>(); dans Main, puis tout fonctionne comme prévu. (Bien que je pense toujours que l’initialisation de la base de données est une opération d’initialisation unique, pas une opération effectuée avec tous les programmes)

12
gbjbaanb

J'ai simplement changé mon Program.cs

de cette

public class Program
{
  public static void Main(string[] args)
  {
    var Host = new WebHostBuilder()
      .UseKestrel()
      .UseContentRoot(Directory.GetCurrentDirectory())
      .UseIISIntegration()
      .UseStartup<Startup>()
      .Build();

    Host.Run();
  }
}

pour ça

public class Program
{
  public static void Main(string[] args)
  {
    BuildWebHost(args).Run();
  }

  public static IWebHost BuildWebHost(string[] args) =>
      WebHost.CreateDefaultBuilder(args)
          .UseStartup<Startup>()
          .Build();
}

Source: https://wildermuth.com/2017/07/06/Program-cs-in-ASP-NET-Core-2-0

5
Srinivas M. P.

Dans les projets 2.0, déplacez l'appel SeedData.Initialize vers la méthode Main de Program.cs:

var Host = BuildWebHost(args);

using (var scope = Host.Services.CreateScope())
{
    var services = scope.ServiceProvider;

    try
    {
        SeedData.Initialize(services, "").Wait();
    }
    catch (Exception ex)
    {
        var logger = services.GetRequiredService<ILogger<Program>>();
        logger.LogError(ex, "An error occurred seeding the DB.");
    }
}

Host.Run();   

Référence: https://docs.Microsoft.com/en-us/aspnet/core/migration/1x-to-2x/#move-database-initialization-code

1

J'ai eu le même problème sur le dernier .Net Core 2.0.3. J'ai un projet séparé avec l'implémentation dbContext (à partir de mon interface personnalisée IUnitOfWork), et au début, la migration fonctionnait parfaitement. Mais après avoir implémenté une autre infrastructure, j'ai l'erreur similaire:

Impossible de créer un objet de type 'TestCoreUnitOfWork'. Ajouter un implémentation de 'IDesignTimeDbContextFactory' vers le projet, ou consultez https://go.Microsoft.com/fwlink/?linkid=851728 pour modèles supplémentaires pris en charge au moment de la conception.

La solution suggérée à propos de l'implémentation IDesignTimeDbContextFactory convient, mais je me demandais pourquoi les migrations avaient déjà fonctionné auparavant? J'ai passé quelques heures à découvrir quel changement de code avait interrompu la migration . En fait, c’était l’initialisation de bootstrappers, où j’ai chargé tous les assemblages référencés (via Assembly.Load ()) à partir de ma solution . Après l’avoir modifiée de manière plus traditionnelle en appelant directement tous les bootstrappers - la migration a recommencé à fonctionner.

Pour résumer et répondre à la question, la première est la cause possible de l'erreur de migration - utilisez Assembly.Load () dans StartUp.ConfigureServices ().

J'espère que cela sera utile à quelqu'un.

1
Pavel K.

J'ai rencontré cette erreur lors de l'utilisation de Npgsql.EntityFrameworkCore.PostgreSQL, si cela compte.

Prise en compte https://docs.Microsoft.com/en-us/aspnet/core/migration/1x-to-2x/#add-configuration-providers

J'ai ajouté ceci à BuildWebHost ()

.ConfigureAppConfiguration((hostContext, config) =>
{
    // delete all default configuration providers
    config.Sources.Clear();
    config.AddJsonFile("appsettings.json", optional: true);
})

alors c'est

public static IWebHost BuildWebHost(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
    .UseStartup<Startup>()
    .ConfigureAppConfiguration((hostContext, config) =>
    {
        // delete all default configuration providers
        config.Sources.Clear();
        config.AddJsonFile("appsettings.json", optional: true);
    })
    .Build();

Maintenant ça marche

0
mkb

Le problème est lié à l’amorçage de la base de données à partir de Startup.Configure ... vous pouvez toujours le faire avec ce travail. Testé et a bien fonctionné

https://garywoodfine.com/how-to-seed-your-ef-core-database/

0
Nick G.

Il semble que EF 2.0 ne fonctionne pas avec les "exemples de données" qui restent de l'ancien modèle de base net du projet.

SampleData.Initialize(app.ApplicationServices);

Je pense 

var context = serviceProvider.GetService<ApplicationDbContext>();
context.Database.Migrate();

cas cette erreur. Je ne suis pas sûr que ce correctif soit correct, mais cela fonctionne.

0
sibvic

Certaines personnes ont dit que vous deviez changer de classe dans Startup.cs, mais je n'ai rien fait de cela, mais j'ai un peu modifié ma classe Program.cs

---------- Ancien fichier --------------

public class Program
{
    public static void Main(string[] args)
    {
        var Host = CreateWebHostBuilder(args).Build();

        using (var scope = Host.Services.CreateScope())
        {
            var services = scope.ServiceProvider;

            try
            {
                var context = services.GetRequiredService<MvcMovieContext>();
                context.Database.Migrate();
                SeedData.Initialize(services);
            }
            catch (Exception ex)
            {
                var logger = services.GetRequiredService<ILogger<Program>>();
                logger.LogError(ex, "An error occurred seeding the DB.");
            }
        }

        Host.Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();
}

----------Nouveau fichier---------

public static void Main(string[] args)
    {
        var Host = BuildWebHost(args);

        using (var scope = Host.Services.CreateScope())
        {
            var services = scope.ServiceProvider;
            try
            {
                var dbContext = scope.ServiceProvider.GetService<MvcMovieContext>();
                //SeeData is a class in my Models folder
                SeedData.Initialize(services);
            }
            catch (Exception ex)
            {
                var logger = services.GetRequiredService<ILogger<Program>>();
                logger.LogError(ex, "An error occurred seeding the DB.");
            }
        }
        Host.Run();
    }

    public static IWebHost BuildWebHost(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .Build();
}
0

Ceci est lié au nouveau processus init de .NET Core 2.0, dans lequel la configuration est gérée différemment (détails ici ).

Si vous avez mis à niveau à partir de 1.x, modifiez vos Program.cs et Startup.cs:

public class Program
{
    public static void Main(String[] args)
    {
        Program.BuildWebHost(args).Run();
    }

    public static IWebHost BuildWebHost(String[] args) =>
        WebHost.CreateDefaultBuilder(args)
               .UseKestrel()
               .UseUrls("http://*:8000")
               .UseStartup<Startup>()
               .Build();
}

public class Statup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    ........
}

Après cette modification, vos migrations devraient fonctionner et une implémentation de IDesignTimeDbContextFactory n'est pas nécessaire.

0
Tobias Punke