Laden...

Warum kann nach Migration auf .NET 5 und EFCore keine Instanz vom DbContext mehr erstellt werden?

Erstellt von Duesmannr vor 3 Jahren Letzter Beitrag vor 3 Jahren 503 Views
D
Duesmannr Themenstarter:in
161 Beiträge seit 2017
vor 3 Jahren
Warum kann nach Migration auf .NET 5 und EFCore keine Instanz vom DbContext mehr erstellt werden?

Hey,

ich migriere gerade meine Projekte auf .NET 5 und so auch EF Core.

Nun ist mir ein Problem bei der Erstellung der Migrationen aufgefallen.

Ausgangssituation zum erstellen der Migrationen.

  1. .NET 5 Class Library mit dem DbContext
    Installierte NuGets:
    Microsoft.EntityFrameworkCore 5.0.0
    Microsoft.EntityFrameworkCore.SqlServer 5.0.0

public class ApplicationDbContext : DbContext
    {
        #region DbSets

        public DbSet<User> Users { get; set; }

        #endregion

        public ApplicationDbContext(DbContextOptions options) : base(options)
        {
        }

        public ApplicationDbContext() : base()
        {
        }
    }

  1. Test Projekt .NET 5 was ich als Start Projekt ausgewählt habe und via der Package Manager Console
add-migration Initial

ausführe. (Default Projekt ist die Class Library).

Bis meinen installierten NuGet Versionen von 3.1.8 funktionierte es auch, weil das Test Projekt ausführbar ist.
Nach updaten auf .NET 5 erhalte ich folgende Fehlermeldung:> Fehlermeldung:

PM> add-migration Initial
Build started...
Build succeeded.
Unable to create an object of type 'ApplicationDbContext'. For the different patterns supported at design time, see
>

In den Breaking Changes von EF Core 5 habe ich keine Änderungen gefunden, die das behindern sollten.

In den Github Issues von efcore habe ich den Artikel gefunden, dass es bei einem funktioniert, der das sagt:

You can add an option such as sqlOptions.MigrationsAssembly();

Habe ich auch gemacht, gleiche Fehlermeldung. Bzw. erwartet die Methode einen Parameter, die Assembly. Habe ich ebenfalls hinzugefügt, aber ändert nichts.

Habt Ihr eine Lösung dafür?
Oder einen Ansatz?

Grüße

T
2.219 Beiträge seit 2008
vor 3 Jahren

Hast du auch mal den letzten Kommentar in dem Issue angeschaut und geprüft.
Das scheint es noch ein Problem mit Interfaces zu geben, was du ggf. haben könntest.

https://github.com/dotnet/efcore/issues/23261

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

D
Duesmannr Themenstarter:in
161 Beiträge seit 2017
vor 3 Jahren

Das scheint es noch ein Problem mit Interfaces zu geben, was du ggf. haben könntest.

Das Problem habe ich gar nicht. Also ich nutze gar keine Interfaces oder sonst was.
Die User Klasse hat nur 3 Properties und die ganze Class Library hat 2 Klasssen (User und ApplicationDbContext).

Es gibt einen "Workaround" dafür, indem man in der gleichen Assembly eine ContextFactory hat:


public class ContextFactory : IDesignTimeDbContextFactory<ApplicationDbContext>
    {
        public ApplicationDbContext CreateDbContext(string[] args)
        {
            DbContextOptionsBuilder<ApplicationDbContext> optionsBuilder = new DbContextOptionsBuilder<ApplicationDbContext>();

            return new(optionsBuilder.Options);
        }
    }

Damit lassen sich nun Migrationen erstellen.

Aber würde das gerne ohne den "Workaround" machen.

2.078 Beiträge seit 2012
vor 3 Jahren

Das ist kein Workaround, sondern Konzept.
Genau für diese Befehle ist die Factory da, die soll einen DbContext mit für DesignTime geeigneten Options erzeugen.

Richtig aufgebaut weiß der DbContext nichts von seiner Konfiguration, denn die kommt von einem DI-Container, da kann man dann DbContextOptions registrieren.
Der DbContext kann aber nur dann sinnvoll automatisch (also ohne Options) erzeugt werden, wenn er sich selber konfigurieren kann - was man ja eigentlich nicht will.
Also entferne mal den Konstruktor mit den Options, ich könnte mir vorstellen, dass es dann funktioniert - vorausgesetzt, der DbContext kann sich selber konfigurieren. Besser wäre aber, Du nutzt die Factory und ziehst die Konfiguration raus.

Ich baue mir dafür normalerweise eine eigene EFCoreTools-Exe ins Projekt, da liegt dann eine Factory drin.
Der erzeugte DbContext stellt die Verbindung zu einer Dummy-Datenbank her und nutzt sie dann für die Migrationen als Abgleich.
Und ich nutze sie, um zu schauen, ob mein Mapping auch wirklich so in der Datenbank ankommt, wie ich mir das vorgestellt habe.

D
Duesmannr Themenstarter:in
161 Beiträge seit 2017
vor 3 Jahren

Also entferne mal den Konstruktor mit den Options, ich könnte mir vorstellen, dass es dann funktioniert - vorausgesetzt, der DbContext kann sich selber konfigurieren. Besser wäre aber, Du nutzt die Factory und ziehst die Konfiguration raus..

Dann funktioniert es.