web-dev-qa-db-ger.com

Nach dem Upgrade auf ASP.NET Core 2.0 können keine Migrationen erstellt werden

Nach dem Upgrade auf ASP.NET Core 2.0 kann ich keine Migrationen mehr erstellen.

Ich erhalte

"Beim Aufrufen der Methode 'BuildWebHost' für die Klasse 'Program' ist ein Fehler aufgetreten. Fortsetzung ohne den Anwendungsdienstanbieter. Fehler: Ein oder mehrere Fehler sind aufgetreten. (Datenbank kann nicht" ... "geöffnet werden, angefordert durch die Anmeldung. Die Anmeldung ist fehlgeschlagen. Anmeldung fehlgeschlagen für Benutzer '...' "

und

Msgstr "Ein Objekt vom Typ" MyContext "kann nicht erstellt werden. Fügen Sie dem Projekt eine Implementierung von" IDesignTimeDbContextFactory "hinzu, oder lesen Sie https://go.Microsoft.com/fwlink/?linkid=851728 für weitere unter unterstützte Muster Design-Zeit. "

Der Befehl, den ich zuvor ausgeführt habe, war $ dotnet ef migrations add InitialCreate --startup-project "..\Web" (aus dem Projekt/Ordner mit dem DBContext).

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

Das ist meine Program.cs

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

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

Sie können eine Klasse hinzufügen, die IDesignTimeDbContextFactory in Ihrem Webprojekt implementiert.

Hier ist der Beispielcode:

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

Navigieren Sie dann zu Ihrem Datenbankprojekt und führen Sie Folgendes über die Befehlszeile aus:

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.

Ressource

65
jaaso

Keine Notwendigkeit für IDesignTimeDbContextFactory.

Lauf 

add-migration initial -verbose 

das wird verraten die Details unter 

Beim Zugriff auf IWebHost in der Klasse 'Program' ist ein Fehler aufgetreten. Weiter ohne den Anwendungsdienstanbieter. 

warnung, die die Wurzel Ursache des Problems ist.

In meinem Fall bestand das Problem darin, ApplicationRole : IdentityRole<int> zu haben und services.AddIdentity<ApplicationUser, IdentityRole>() aufzurufen, was den folgenden Fehler verursachte

System.ArgumentException: GenericArguments[1], 'Microsoft.AspNetCore.Identity.IdentityRole', 
on 'Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore`9[TUser,TRole,TContext,
TKey,TUserClaim,TUserRole,TUserLogin,TUserToken,TRoleClaim]' violates the constraint of type 'TRole'.
---> System.TypeLoadException: GenericArguments[1], 'Microsoft.AspNetCore.Identity.IdentityRole', 
on 'Microsoft.AspNetCore.Identity.UserStoreBase`8[TUser,TRole,TKey,TUserClaim,
TUserRole,TUserLogin,TUserToken,TRoleClaim]' violates the constraint of type parameter 'TRole'.
16
tchelidze

In meinem Fall war die Ursache des Problems mehrere Startprojekte. Ich habe drei Projekte in meiner Lösung: Mvc, Api und Dal. DbContext und Migrationen im Dal-Projekt.

Ich hatte mehrere Startprojekte konfiguriert. Sowohl Mvc- als auch Api-Projekte wurden ausgeführt, als ich auf Start geklickt habe. Aber in diesem Fall habe ich diesen Fehler bekommen.

"Ein Objekt vom Typ" MyContext "kann nicht erstellt werden. Fügen Sie dem Projekt eine Implementierung von" IDesignTimeDbContextFactory "hinzu, oder lesen Sie https://go.Microsoft.com/fwlink/?linkid=851728 für weitere Informationen zur Entwurfszeit unterstützte Muster. "

Ich konnte die Migration erfolgreich hinzufügen, nachdem ich Mvc als einziges Startprojekt festgelegt und Dal in der Package Manager-Konsole ausgewählt hatte.

9

Fügen Sie in der AppContext.cs neben der AppContext-Klasse eine weitere Klasse hinzu:

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

Damit lösen Sie Ihr zweites Problem:

Msgstr "Kann kein Objekt vom Typ 'MyContext' erstellen. Fügen Sie dem Projekt eine Implementierung von 'IDesignTimeDbContextFactory' hinzu.

Danach können Sie add-migration Initial ausführen und durch Ausführen von update-database command ..__ ausführen. Wenn Sie jedoch diese Befehle ausführen, wenn sich noch keine Datenbank in Ihrem lokalen SqlServer befindet, werden Sie erhalten die Warnung wie Ihre erste Fehlermeldung: "Eine Fehlermeldung

trat beim Aufruf der Methode 'BuildWebHost' in der Klasse 'Program' auf ... Die Anmeldung fehlgeschlagen. Login ist fehlgeschlagen für den Benutzer '...'"

Es ist jedoch kein Fehler, da die Migration erstellt wird und ausgeführt werden kann. Ignorieren Sie diesen Fehler also zum ersten Mal, und letzteres tritt nicht mehr auf, da Db vorhanden ist.

4
borisdj

Sie können diese Lösung aus dieser Diskussion ausprobieren, die von diesem Beitrag inspiriert wurde. 

public static IWebHost MigrateDatabase(this IWebHost webHost)
{
    using (var scope = webHost.Services.CreateScope())
    {
        var services = scope.ServiceProvider;

        try
        {
            var db = services.GetRequiredService<MyContext>();
            db.Database.Migrate();
        }
        catch (Exception ex)
        {
            var logger = services.GetRequiredService<ILogger<Program>>();
            logger.LogError(ex, "An error occurred while migrating the database.");
        }
    }

    return webHost;
}
public static void Main(string[] args)
{
    BuildWebHost(args)
        .MigrateDatabase()
        .Run();
}
3
user2771704

Was mir wirklich geholfen hat, war dieser Artikel: https://elanderson.net/2017/09/unable-to-anlegen-einem_objekt-von-typ-anwendung-anwendungdbcontext-add-animplementationof-idesigntimedbcontextfactory/

Die Grundidee ist, dass bei der Umstellung von .net Core 1 auf 2 die gesamte DB-Initialisierung aus der StartUp.cs und in die Program.cs verschoben werden sollte. Andernfalls versuchen die EF-Tasks Ihre DB-Instanzen auszuführen, wenn Sie Tasks ausführen.

"In den offiziellen Migrationsdokumenten ( https://docs.Microsoft.com/en-us/ef/core/m Miscellaneous/1x-2x-upgrade ) gibt es einen Abschnitt" Nice "mit dem Titel" Move database initialization code " Ich schien es vermisst zu haben. Bevor Sie also irgendwelche Kaninchenlöcher hinuntergehen, stellen Sie sicher, dass dies nicht der Grund dafür ist, dass Sie eine Implementierung von IdesignTimeDbContextFactory hinzufügen müssen. "

3
Rtype

bitte vergewissern Sie sich, dass Sie die Referenz haben

<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.0.0" />
3
Vladmir

In meinem Fall bekam ich das Problem, weil ich eine Methode namens SeedData.EnsurePopulated () hatte, die in meiner Startup.cs -Datei aufgerufen wurde.

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

Die Arbeit von SeedData class besteht darin, der Datenbanktabelle Anfangsdaten hinzuzufügen. Der Code lautet:

public static void EnsurePopulated(IApplicationBuilder app)
    {
        ApplicationDbContext context = app.ApplicationServices.GetRequiredService<ApplicationDbContext>();
        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();
        }
    }

L&OUML;SUNG

Bevor Sie eine Migration durchführen, kommentieren Sie einfach den Aufruf von SeedData class in der Datei Startup.cs aus.

// SeedData.EnsurePopulated(app);

Das hat mein Problem gelöst und ich hoffe, dass Ihr Problem auf dieselbe Weise gelöst wird.

2
yogihosting

Zuvor haben Sie die Startdaten in der Methode Configure in Startup.cs konfiguriert. Es wird jetzt empfohlen, die Configure-Methode nur zum Einrichten der Anforderungspipeline zu verwenden. Der Anwendungsstartcode gehört zur Main-Methode.

Die überarbeitete Main-Methode. Fügen Sie den Program.cs die folgenden Verweise hinzu:

using Microsoft.Extensions.DependencyInjection;

using 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<MyDbConext>();
            DbInitializer.Initialize(context);
        }
        catch (Exception ex)
        {
            var logger = services.GetRequiredService<ILogger<Program>>();
            logger.LogError(ex, "An error occurred while seeding the database.");
        }
    }

    Host.Run();
}

2
Miguel Torres C

Wenn Sie diese IDesignTimeDbContextFactory-Sache vermeiden möchten: Stellen Sie nur sicher, dass Sie keine Seed -Methode in Ihrem Startvorgang verwenden. Ich habe bei meinem Start eine statische Startmethode verwendet, die diesen Fehler für mich verursacht hat.

2
codeYouLaterBro

Es gibt ein Problem mit dem Start von ef db aus Startup.Configure in 2.0 ... Sie können es trotzdem mit dieser Arbeit umgehen. Getestet und funktionierte gut

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

2
Nick G.

Eine bessere Lösung:

Wenn Ihr Startprojekt eine ASP.NET Core-App ist, versuchen die Tools, das DbContext-Objekt vom Dienstanbieter der Anwendung abzurufen.

Das Tool versucht zunächst, den Dienstanbieter abzurufen, indem Sie Program.BuildWebHost() aufrufen und auf die IWebHost.Services-Eigenschaft zugreifen.

fügen Sie diese Methode nach Main Method in Program.cs hinzu

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

Von

https://docs.Microsoft.com/en-us/ef/core/m Miscellaneous/cli/dbcontext-creation

Wenn Sie eine neue ASP.NET Core 2.0-Anwendung erstellen, lautet dieser Hook standardmäßig enthalten. In früheren Versionen von EF Core und ASP.NET Core wurde Die Tools versuchen, Startup.ConfigureServices direkt aufzurufen, um Den Dienstanbieter der Anwendung erhalten, dieses Muster jedoch nicht mehr funktioniert ordnungsgemäß in ASP.NET Core 2.0-Anwendungen. Wenn Sie ein Upgrade durchführen einer ASP.NET Core 1.x-Anwendung bis 2.0 können Sie Ihr Programm .__ ändern. Klasse, um dem neuen Muster zu folgen.

Fügen Sie Factory in .NET Core 2.x hinzu

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

            return new BloggingContext(optionsBuilder.Options);
        }
    }
2

Ich hatte dieses Problem und dieses Problem gelöst durch Set -> Web Application (enthaltenes Programm.cs) Projekt auf -> "Als Startup-Projekt festlegen"

Führen Sie dann -> add-migration initial -verbose aus 

in der Package Manager Console

Als Startprojekt festlegen

1
Ali Ahmadi

Ich bin auf dasselbe Problem gestoßen. Ich habe zwei Projekte in der Lösung. welche

  1. API
  2. Services und Repos, die Kontextmodelle enthalten

Ursprünglich wurde das API-Projekt als Startprojekt festgelegt.

Ich habe das Startprojekt in ein Projekt mit Kontextklassen geändert. Wenn Sie Visual Studio verwenden, können Sie ein Projekt wie folgt als Startprojekt festlegen:

öffnen Sie den Projektmappen-Explorer. >> Klicken Sie mit der rechten Maustaste auf das Kontextprojekt. >> Wählen Sie Als Startprojekt festlegen

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

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

Benennen Sie BuildWebHost einfach in CreateWebHostBuilder um, da die Migration diese Methode standardmäßig verwendet

0
sherox

Sie können auch im Startklassenkonstruktor verwenden, um der Konfiguration eine Json-Datei (in der sich die Verbindungszeichenfolge befindet) hinzuzufügen. Beispiel:

    IConfigurationRoot _config;
    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json");

        _config = builder.Build();
    }
0
Vio

Ich habe dasselbe Problem, seit ich auf das alte Microsoft.EntityFrameworkCore.Tools.DotNet verwiesen habe

<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="1.0.0" />

Nach dem Upgrade auf die neuere Version wurde es behoben

0
vinayak hegde

Stellen Sie zunächst sicher, dass Sie Ihre Datenbank in Startup.cs konfiguriert haben. In meinem Fall wurde dieser Fehler angezeigt, da ich in Startup.cs das Folgende nicht angegeben habe.

    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection"), x => x.MigrationsAssembly("<Your Project Assembly name where DBContext class resides>")));
0
immirza

Ich hatte dieses Problem in einer Lösung, die hat:

  • ein .NET Core 2.2 MVC-Projekt
  • ein .NET Core 3.0 Blazor-Projekt
  • Der DB-Kontext in einem .NET Standard 2.0-Klassenbibliotheksprojekt

Ich erhalte die Meldung "Objekt kann nicht erstellt werden ...", wenn das Blazor-Projekt als Startprojekt festgelegt ist, aber nicht, wenn das MVC-Projekt als Startprojekt festgelegt ist.

Das ist mir ein Rätsel, denn in der Package Manager-Konsole (in der ich die Migration erstelle) habe ich das Standardprojekt auf eine C # -Klassenbibliothek festgelegt, die tatsächlich den DB-Kontext enthält, und ich gebe auch den DB-Kontext in an Mein Aufruf an add-migration add-migration MigrationName -context ContextName, daher ist es seltsam, dass Visual Studio sich darum kümmert, welches Startprojekt derzeit festgelegt ist.

Ich vermute, der Grund dafür ist, dass der PMC, wenn das Blazor-Projekt das Startprojekt ist, die Version von .NET als Core 3.0 aus dem Startprojekt ermittelt und dann versucht, diese zu verwenden, um die Migrationen für die .NET Standard 2.0-Klasse auszuführen Bibliothek und trifft eine Art Konflikt.

Unabhängig von der Ursache wurde das Problem behoben, indem das Startprojekt in das MVC-Projekt geändert wurde, das auf Core 2.2 und nicht auf das Blazor-Projekt abzielt

0
tomRedox

Ich hatte das gleiche Problem. Ich habe gerade die Anwendung in application.jason geändert und das Problem behoben

0
AliAzra

Für mich war es, weil ich den Output Type meines Startprojekts von Console Application in Class Library geändert habe.

Die Rückkehr zu Console Application hat den Trick ausgeführt.

0
Robouste

In der Datei appsettings.json des Hauptprojekts hatte ich "Copy to Output directory" auf "Copy always" gesetzt und es funktionierte.

0
geet

Beispiel-DB-Kontextklasse für .NET-Konsolenanwendungen

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.Extensions.Configuration;
using System.IO;

namespace EmailServerConsole.Data
{
    public class EmailDBContext : DbContext
    {
        public EmailDBContext(DbContextOptions<EmailDBContext> options) : base(options) { }
        public DbSet<EmailQueue> EmailsQueue { get; set; }
    }

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