wake-up-neo.com

Ausnahme, wenn Code zum ersten Mal versucht hat, eine Datenbank zu erstellen

Ich habe eine neue ASP.NET MVC 4-Anwendung erstellt und möchte, dass sie zuerst Code verwendet. Es scheint jedoch nicht, dass die Datenbankdatei anfänglich erstellt wird, wenn sie noch nicht vorhanden ist. Wenn ich die .mdf-Datei aus dem App_Data-Ordner lösche, erhalte ich die folgende Ausnahme, wenn die App versucht, auf die Datenbank zuzugreifen:

System.Data.SqlClient.SqlException: Cannot attach the file '<path-to-db-file>.mdf' as database '<my-db-file-name>'.

Wenn ich es in der App im Debugger ausführe, kann ich sehen, dass die Ausnahme in der InitializeSimpleMembershipAttribute :: OnActionExecuting-Methode auftritt, wenn LazyInitializer.EnsureInitialized aufgerufen wird. Die abgefangene Ausnahme ist:

[System.Reflection.TargetInvocationException]   {"Exception has been thrown by the target of an invocation."}   System.Reflection.TargetInvocationException

Mit einer inneren Ausnahme von:

[System.InvalidOperationException]  {"The ASP.NET Simple Membership database could not be initialized. For more information, please see http://go.Microsoft.com/fwlink/?LinkId=256588"} System.InvalidOperationException

Was dann die erste Ausnahme hat, die ich oben als die innere Ausnahme davon erwähnt habe.

Irgendwelche Ideen, was ich falsch mache?

Update

Ich habe es gerade mit einer brandneuen MVC4-App ausprobiert. Ich kann es folgendermaßen replizieren:

  1. Erstellen Sie die MVC-App im VS-Assistenten.
  2. Starten Sie die App zum ersten Mal und wechseln Sie zur Anmeldeseite (beachten Sie, dass die MDF-Datei jetzt generiert wird).
  3. Löschen Sie die MDF-Datei und kehren Sie zur Anmeldeseite zurück. Die Ausnahme wird jetzt ausgelöst.
24
Dan

Ich bin in das gleiche Problem geraten und habe meine Lösung gefunden hier . Sie müssen nur LocalDb stoppen, indem Sie den VS-Entwicklerbefehl Prompt öffnen und eingeben (ohne Anführungszeichen):

"sqllocaldb.exe stop v11.0"

"sqllocaldb.exe löschen v11.0"

Beim nächsten Mal regeneriert EF sowohl die Datei als auch die Datenbank.

9
moranlf

Wenn Sie in die InitializeSimpleMembershipAttribute-Klasse Ihrer Anwendung einsteigen, wird die folgende überschriebene Methode der ActionFilterAttribute-Klasse angezeigt, von der sie erbt:

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        // Ensure ASP.NET Simple Membership is initialized only once per app start
        LazyInitializer.EnsureInitialized(ref _initializer, ref _isInitialized, ref _initializerLock);
    }

Beachten Sie diesen Kommentar. Die Anwendung überprüft einmal pro Lauf, um sicherzustellen, dass die einfache Mitgliedschaft ordnungsgemäß initialisiert wurde. Schauen Sie sich die privaten Variablen oben in der Klasse an:

    private static SimpleMembershipInitializer _initializer;
    private static object _initializerLock = new object();
    private static bool _isInitialized;

Sie sind alle statisch und werden als Refs übergeben. Das Wichtige für Ihre Situation ist _isInitialized. Bei LazyInitializer.EnsureInitialized wird das Flag _isInitialized überprüft. Wenn es falsch ist, wird das ref-Ziel, das übergeben wird, initialisiert. In diesem Fall wird der _initializer vom Typ SimpleMembershipInitializer verwendet. An diesem Punkt wird das Flag auf "true" gesetzt und es geht weiter. Wenn LazyInitializer.EnsureInitialized feststellt, dass das Flag wahr ist, wird nur das Ziel zurückgegeben. Da dieses Flag eine statische Variable ist, behält es seinen Wert für die Lebensdauer der Anwendung bei. Dies bedeutet, dass EnsureInitialized nach der ersten Initialisierung immer das Ziel zurückgibt, auch wenn die Datenbankdatei nicht mehr vorhanden ist. Mit anderen Worten, wenn Sie die .mdf-Datei nach der Initialisierung löschen, weiß die Anwendung dies nicht und Ausnahmen werden ausgelöst, wenn die App versucht, aus der Datenbank zu lesen oder zu schreiben. Um dieses Problem zu beheben, müssen Sie die Anwendung neu starten. Dies bedeutet, dass Sie den dev-Server beenden, wenn Sie das verwenden, oder die Anwendung in IIS neu starten.

Das ist also das Problem, mit dem Sie konfrontiert sind, aber ich vermute, dass viele der Leute, die sich dieser Frage stellen, ein ähnliches, aber ein anderes Problem haben, bei dem sie eine Fehlermeldung erhalten, die der folgenden ähnelt, wenn Sie versuchen, sich anzumelden:

CREATE FILE hat Betriebssystemfehler 5 (Zugriff wurde verweigert.) Beim Versuch, die physische Datei 'C:\Pfad\zu\Ihr\Projekt\Anwendungsdaten\dbfile.mdf' zu öffnen oder zu erstellen, erstellt. CREATE DATABASE ist fehlgeschlagen. Einige der aufgeführten Dateinamen konnten nicht erstellt werden. Überprüfen Sie die verwandten Fehler.

Das ist sehr einfach zu lösen, damit ich das hier auch schnell besprechen kann.

Standardmäßig verwendet Visual Studio 2012 eine reduzierte Version von SQL Server Express, die als LocalDB bezeichnet wird. LocalDB startet einen untergeordneten Prozess der Anwendung. Wenn Sie Ihre Anwendung auf dem Entwicklungsserver von Visual Studio ausführen (z. B. http: // localhost: [Anschluss] wird in Ihrem Browser angezeigt), führen Sie beide Anwendungen aus und LocalDB unter Ihrem Benutzerkonto, nicht unter SYSTEM oder NETWORKSERVICE. Um dies zu beheben, müssen Sie Ihrem Benutzer Modify-Berechtigungen für den App_Data-Ordner Ihres Projekts zuweisen. Versuchen Sie es erneut, und die .mdf-Datei sollte erfolgreich erstellt werden.

Wenn Sie neugierig sind, erfahren Sie mehr über LocalDB hier.

4
joelmdev

Sie können die Initialisierung der Code First-Datenbank in der Application_Start-Methode der Datei "Global.asax" im Stammordner Ihres Projekts wie folgt durchführen:

    protected void Application_Start()
    {
        Database.SetInitializer<MyDBContext>(null);
    }

Wenn Sie SetInitializer mit null übergeben, werden Ihre Datenbanktabellen nicht erstellt oder geändert. Sie sollten dies manuell tun.

Der Grund, warum die Datenbank nicht neu generiert wird, besteht darin, dass Application_Start während der Anwendungslebensdauer nur einmal ausgelöst wird.

2
Mohsen Afshin

Der von MVC generierte Code funktioniert mit einer Datenbankverbindungszeichenfolge mit dem Namen "DefaultConnection". Wenn Sie in Web.config einen anderen Namen verwendet haben, müssen Sie auf diesen Namen verweisen:

  1. InitializeSimpleMembershipAttribute.SimpleMembershipInitializer.ctor () in InitializeSimpleMembershipAttribute.cs).
  2. UsersContext.ctor () in AccountModel.cs

(oder suchen Sie einfach nach "DefaultConnection" in Ihrem Projekt).

2
ury

Sie sollten automatisch erstellte .mdf-Dateien im Explorer nur über die SQL-Verwaltungstools oder im Objekt-Explorer löschen. 

Das Problem, das Sie erhalten (und in den von Ihnen angegebenen Schritten replizieren können) besteht darin, dass die Datenbank noch in LocalDb registriert ist.

1
Evonet

Sie müssen Ihre IISExpress-Instanz stoppen und erneut starten (durch Drücken von F5 in Ihrem Visual Studio). Dann können Sie die Datenbank erneut erstellen.

0
Will Huang

was für mich behoben wurde, als ich diesen Fehler erhielt, ist, dass ich die Verbindungszeichenfolge in der Datei App.config meines VS-Projekts geändert habe.

Ich habe dies in die Verbindungszeichenfolge eingefügt:

  <connectionStrings>
<add name="Blog" connectionString="Data Source=(LocalDb)\MSSQLLocalDB;Integrated Security=true;AttachDbFileName=C:\Users\kostadin\Database1.mdf" providerName="System.Data.SqlClient" />

Hoffe das hilft jemand anderem.

0