Imansible creare migrazioni dopo l’aggiornamento a ASP.NET Core 2.0

Dopo l’aggiornamento a ASP.NET Core 2.0, non riesco più a creare migrazioni.

Sto arrivando

“Si è verificato un errore durante il richiamo del metodo ‘BuildWebHost’ sulla class ‘Programma’. Continua senza il fornitore del servizio dell’applicazione Errore: si sono verificati uno o più errori. (Imansible aprire il database” … “richiesto dal login. non riuscito per l’utente ‘…’ ”

e

“Imansible creare un object di tipo” MyContext “. Aggiungere un’implementazione di” IDesignTimeDbContextFactory “al progetto oppure consultare https://go.microsoft.com/fwlink/?linkid=851728 per ulteriori modelli supportati in fase di progettazione.”

Il comando che ho eseguito in precedenza era $ dotnet ef migrations add InitialCreate --startup-project "..\Web" (dal progetto / cartella con DBContext).

Stringa di connessione: "Server=(localdb)\\mssqllocaldb;Database=database;Trusted_Connection=True;MultipleActiveResultSets=true"

Questo è il mio Program.cs

  public class Program { public static void Main(string[] args) { BuildWebHost(args).Run(); } public static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup() .Build(); } 

È ansible aggiungere una class che implementa IDesignTimeDbContextFactory all’interno del proprio progetto Web.

Ecco il codice di esempio:

 public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory { public CodingBlastDbContext CreateDbContext(string[] args) { IConfigurationRoot configuration = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json") .Build(); var builder = new DbContextOptionsBuilder(); var connectionString = configuration.GetConnectionString("DefaultConnection"); builder.UseSqlServer(connectionString); return new CodingBlastDbContext(builder.Options); } } 

Quindi, accedere al progetto del database ed eseguire quanto segue dalla riga di comando:

 dotnet ef migrations add InitialMigration -s ../Web/ dotnet ef database update -s ../Web/ -s stands for startup project and ../Web/ is the location of my web/startup project. 

risorsa

In AppContext.cs oltre alla class AppContext aggiungi un’altra class:

 // required when local database deleted public class ToDoContextFactory : IDesignTimeDbContextFactory { public AppContext CreateDbContext(string[] args) { var builder = new DbContextOptionsBuilder(); builder.UseSqlServer("Server=localhost;Database=DbName;Trusted_Connection=True;MultipleActiveResultSets=true"); return new AppContext(builder.Options); } } 

Questo risolverà il tuo secondo problema:

“Imansible creare un object di tipo” MyContext “. Aggiungere un’implementazione di” IDesignTimeDbContextFactory “al progetto,

Successivamente sarà ansible aggiungere-migration Initial ed eseguirlo eseguendo il comando update-database . Tuttavia, se si eseguono questi comandi quando non c’è ancora un Database nel proprio SqlServer locale si otterrà l’avviso come il primo errore: “Un errore

si è verificato durante il richiamo del metodo ‘BuildWebHost’ sulla class ‘Programma’ … L’accesso non è riuscito. Accesso non riuscito per l’utente ‘…’ ”

Ma non è un errore perché la migrazione verrà creata e può essere eseguita. Quindi, ignora questo errore per la prima volta e, poiché Db esisterà, non accadrà più.

si prega di verificare di avere il riferimento

  

Puoi provare questa soluzione da questa discussione , che è stata ispirata da questo post .

 public static IWebHost MigrateDatabase(this IWebHost webHost) { using (var scope = webHost.Services.CreateScope()) { var services = scope.ServiceProvider; try { var db = services.GetRequiredService(); db.Database.Migrate(); } catch (Exception ex) { var logger = services.GetRequiredService>(); logger.LogError(ex, "An error occurred while migrating the database."); } } return webHost; } public static void Main(string[] args) { BuildWebHost(args) .MigrateDatabase() .Run(); } 

Qualcosa che mi ha veramente aiutato è stato questo articolo: https://landerson.net/2017/unable-to-create-an-object-of-type-applicationdbcontext-add-an-implementation-of-idesigntimedbcontextfactory/

L’idea di base è che nel passaggio da .net core 1 a 2 tutte le inizializzazioni del db dovrebbero essere spostate fuori da StartUp.cs e in Program.cs. In caso contrario, le attività EF tentano di eseguire i DB in esecuzione durante le attività.

“C’è una bella sezione nei documenti ufficiali sulla migrazione ( https://docs.microsoft.com/en-us/ef/core/miscellaneous/1x-2x-upgrade ) intitolata” Sposta il codice di inizializzazione del database “che mi sembrava di avere mancato. Quindi, prima di buttare giù qualsiasi buco di rabbitmq come ho fatto assicurarmi che questo non è ciò che sta causando la necessità di aggiungere un’implementazione di IdesignTimeDbContextFactory. ”

Nel mio caso, la causa del problema era costituita da più progetti di avvio. Ho tre progetti nella mia soluzione: Mvc, Api e Dal. DbContext e Migrations nel progetto Dal.

Avevo configurato più progetti di avvio. Entrambi i progetti Mvc e Api erano in esecuzione quando ho fatto clic su Start. Ma in questo caso ho ricevuto questo errore.

“Imansible creare un object di tipo” MyContext “. Aggiungere un’implementazione di” IDesignTimeDbContextFactory “al progetto oppure consultare https://go.microsoft.com/fwlink/?linkid=851728 per ulteriori modelli supportati in fase di progettazione.”

Potrei aggiungere con successo la migrazione dopo aver impostato Mvc come unico progetto di avvio e aver selezionato Dal nella console di Gestione pacchetti.

C’è un problema con ef seeding db da Startup.Configure in 2.0 … puoi ancora farlo con questo lavoro. Testato e funzionato bene

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

Una soluzione migliore:

Se il progetto di avvio è un’app di ASP.NET Core , gli strumenti tentano di ottenere l’object DbContext dal fornitore di servizi dell’applicazione.

Lo strumento tenta innanzitutto di ottenere il fornitore di servizi richiamando Program.BuildWebHost() e accedendo alla proprietà IWebHost.Services .

aggiungi questo metodo dopo Main Method in Program.cs

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

Nel mio caso ho avuto il problema perché avevo chiamato un metodo chiamato SeedData.EnsurePopulated () sul mio file Startup.cs .

 public class Startup { public Startup(IConfiguration configuration) => Configuration = configuration; public IConfiguration Configuration { get; } public void ConfigureServices(IServiceCollection services) { // } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseDeveloperExceptionPage(); app.UseStatusCodePages(); app.UseStaticFiles(); app.UseSession(); app.UseMvc(routes => { // }); SeedData.EnsurePopulated(app); } } 

Il lavoro della class SeedData consiste nell’aggiungere i dati iniziali alla tabella del database. Il codice è:

 public static void EnsurePopulated(IApplicationBuilder app) { ApplicationDbContext context = app.ApplicationServices.GetRequiredService(); context.Database.Migrate(); if (!context.Products.Any()) { context.Products.AddRange( new Product { Name = "Kayak", Description = "A boat for one person", Category = "Watersports", Price = 275 }, .... ); context.SaveChanges(); } } 

SOLUZIONE

Prima di eseguire la migrazione è sufficiente commentare la chiamata della class SeedData nel file Startup.cs.

 // SeedData.EnsurePopulated(app); 

Questo ha risolto il mio problema e spero che anche il tuo problema venga risolto allo stesso modo.

In precedenza, i dati seed sono stati configurati nel metodo Configure in Startup.cs. Si consiglia ora di utilizzare il metodo Configure solo per impostare la pipeline della richiesta. Il codice di avvio dell’applicazione appartiene al metodo Main.

Il metodo Main refactored. Aggiungere i seguenti riferimenti a Program.cs:

using Microsoft.Extensions.DependencyInjection;

utilizzando MyProject.MyDbContextFolder;

 public static void Main(string[] args) { var host = BuildWebHost(args); using (var scope = host.Services.CreateScope()) { var services = scope.ServiceProvider; try { var context = services.GetRequiredService(); DbInitializer.Initialize(context); } catch (Exception ex) { var logger = services.GetRequiredService>(); logger.LogError(ex, "An error occurred while seeding the database."); } } host.Run(); } 

Ho avuto lo stesso problema da quando mi riferivo a old- Microsoft.EntityFrameworkCore.Tools.DotNet

  

Dopo l’aggiornamento alla versione più recente è stato risolto

Nel file appsettings.json del progetto principale, avevo impostato la cartella “Copia in uscita” su “Copia sempre” e funzionava.

A partire dal

https://docs.microsoft.com/en-us/ef/core/miscellaneous/cli/dbcontext-creation

Quando si crea una nuova applicazione ASP.NET Core 2.0, questo hook è incluso per impostazione predefinita. Nelle versioni precedenti di EF Core e ASP.NET Core, gli strumenti tentano di richiamare Startup.ConfigureServices direttamente per ottenere il provider di servizi dell’applicazione, ma questo schema non funziona più correttamente nelle applicazioni ASP.NET Core 2.0. Se si aggiorna un’applicazione ASP.NET Core 1.x alla versione 2.0, è ansible modificare la class Program per seguire il nuovo pattern.

Aggiungi Factory in. Net Core 2.x

 public class BloggingContextFactory : IDesignTimeDbContextFactory { public BloggingContext CreateDbContext(string[] args) { var optionsBuilder = new DbContextOptionsBuilder(); optionsBuilder.UseSqlite("Data Source=blog.db"); return new BloggingContext(optionsBuilder.Options); } } 

Nel mio caso questo errore si è verificato a causa della rimozione di MyDbContext da ConfigureServices a causa di alcuni modelli di progettazione. Controllalo. In Startup.cs => ConfigureServices aggiungi queste righe:

 var connectionString = "Application Connection String!!!"; services.AddDbContext(c => c.UseSqlServer(connectionString));