11

ich diese Störung erhalte, wenn ich versuche Code erste Migrationen zu verwenden.Getting 'Context ist nicht konstruierbar. Fügen Sie einen Standard-Konstruktor oder bieten eine Implementierung von IDbContextFactory.“

Mein Kontext einen Konstruktor mit dem Verbindungsnamen hat.

public class VeraContext : DbContext, IDbContext 
{ 
    public VeraContext(string NameOrConnectionStringName = "VeraDB") 
     : base(NameOrConnectionStringName) 
    { 
    } 

    public IDbSet<User> Users { get; set; } 
    public IDbSet<Product> Products { get; set; } 
    public IDbSet<IntCat> IntCats { get; set; } 
} 

Diese Verbindungsname wird mit ninject injiziert, wenn das Projekt läuft, ich habe es auch als Standard wie in dem obigen Code angegeben, aber das hat nicht geholfen.

kernel.Bind<IDbContext>() 
    .To<VeraContext>() 
    .WithConstructorArgument("NameOrConnectionStringName", "VeraDB"); 

wenn ich versuche, Migrationen hinzufügen „Enable-Mi grations“ist führt den Fehler auf:

The target context 'VeraData.EF.Infrastructure.VeraContext' is not constructible. Add a default constructor or provide an implementation of IDbContextFactory.

Wenn ich den Konstruktor von VeraContext entfernen wird es funktionieren, aber eine andere Datenbank mit VeraData.EF.Infrastructure.VeraContext wie der Name erzeugt.

Ich gehe davon aus, dass ninject nur die Verbindungszeichenfolge übergibt, wenn das Projekt ausgeführt wird und nicht, wenn ich Code erste Migrationen verwende. Wie auch immer, ich kann einen Standard für den Verbindungsnamen eingeben/bereitstellen, wenn Code-Erstmigrationen verwendet werden?

+1

Das ganze ninject Zeug passiert, wenn jemand irgendwo einen 'Kernel.Get' macht.Sie müssen entweder einen Standard-Ctor hinzufügen oder darauf warten, dass jemand Ihnen sagt, wie Sie die Migrations-Objekte anhängen können, um Objekte über Ninject zu konstruieren (was ich denke, was Sie tun!). –

+0

Sie müssten die 'IDbContextFactory' implementieren, damit die Ergebnisse konsistent sind (oder Ihre Migration vom Code wird nicht funktionieren usw.). Im Wesentlichen benötigen Sie eine Standard-Ctor (das ist der Fehler) - aber nur die Implementierung würde zu Problemen führen. – NSGaga

+0

Die 'IDbContextFactory' ist nicht gut für die Injektion, es wird einfach nicht funktionieren. Kann den Punkt noch nicht sehen ... – nicodemus13

Antwort

16

Im Wesentlichen benötigen Sie eine Standard-Ctor (das ist der Fehler) - aber nur die Implementierung würde zu Problemen führen.

Sie müssten die IDbContextFactory für die Ergebnisse konsistent implementieren (oder Ihre Migration von Code wird nicht funktionieren usw.).

Migrations actually call your default constructor to make a connection. So you're other ctor won't matter much.

Hier ist die grundlegende Fabrik ...

public class MyContextFactory : IDbContextFactory<MyContext> 
{ 
    public MyContext Create() 
    { 
     return new MyDBContext("YourConnectionName"); 
    } 
} 

Sie mit Einspritzung kombinieren sollte, dass injizieren und Ihre DbContext zu konstruieren, wie Sie es wünschen.

+0

Könnten Sie erklären, was Sie weiter meinen, Sie können nicht injizieren, da 'Create()' keine Parameter übernimmt und es einen Standardkonstruktor geben muss, der immer ist der eine genannt- daher nirgends zu injizieren. Zumindest keine Konstruktorinjektion. – nicodemus13

+0

@ nicodemus13 es war vor langer Zeit, aber wie ich mich erinnere - es ist eine konsistente DbContext Konstruktion zu gewährleisten. oft ruft EF standardmäßig ctor durch automatisch auf, ob Sie es wollen oder nicht, also müssen Sie einen haben, und ctor wird nicht aufgerufen. Factory ist hauptsächlich für EF-Aufrufe, Sie können die Injektion auf DbContext normalerweise verwenden. Aber b) Soweit ich mich erinnere, haben die meisten IoC-Container (ich verwende ninject nicht viel) eine Möglichkeit, z.B. container.Create und dann einige anonyme Methode, um die Fabrik zu engagieren (wenn die Fabrik komplexer ist, so müssen Sie durchlaufen, sonst wie ich schon sagte) – NSGaga

+1

@NSGaga - Jeder Grund, warum wir nicht den DbContext oder die Verbindungszeichenfolge injizieren können in die MyContextFactory über Konstruktor und dann den DbContext zurückgeben, anstatt einen neuen DbContext in der create Methode neu zu erstellen? –

1

zur Ergänzung @ nccsbim071 Antwort muss ich noch etwas hinzufügen ... diese Option mag Konstruktor nicht mit Standardparametern ... zum Beispiel:

public MyContext(bool paramABC = false) : base("name=Entities") {...} 

Stattdessen müssen Sie einen Nicht-Parameter (Standard) -Konstruktor und den Parameter-Konstruktor wie alte Mode Weise erstellen.

public MyContext() :base("name=Entities") {...} 
public MyContext(bool paramABC) : this() {...} 

HINWEIS:

  • Entities bedeutet in diesem Fall die Verbindung string name ... Vereinbarungs der Name des Kontexts der gleiche wie der Name Verbindungszeichenfolge ist und da MyContext ist nicht das gleiche als Entities, muss es manuell angegeben werden.
Verwandte Themen