web-dev-qa-db-ja.com

コードが最初にデータベースを作成しようとしたときの例外

新しいASP.NETMVC 4アプリケーションを作成しましたが、最初にコードを使用したいと思います。ただし、データベースファイルがまだ存在しない場合、最初はデータベースファイルを作成していないようです。 App_Dataフォルダーから.mdfファイルを削除すると、アプリがデータベースにアクセスしようとしたときに次の例外が発生します。

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

デバッガーのアプリで実行すると、LazyInitializer.EnsureInitializedを呼び出すときに、InitializeSimpleMembershipAttribute :: OnActionExecutingメソッドで例外が発生していることがわかります。キャッチされた例外は次のとおりです。

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

以下の内部例外を除いて:

[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

次に、その内部例外として上記の最初の例外があります。

私が間違っていることについて何か考えはありますか?

更新

まったく新しいMVC4アプリで試してみました。次のようにして複製できます。

  1. VSウィザードでMVCアプリを作成します。
  2. アプリを初めて実行し、ログインページに移動します(mdfファイルが生成されることに注意してください)。
  3. Mdfファイルを削除し、ログインページに戻ります。例外がスローされるようになりました。
24
Dan

同じ問題に遭遇し、私の解決策を見つけました ここ 。あなたがしなければならないのは、VS開発者コマンドプロンプトを開いてLocalDbを停止し、(引用符なしで)入力することだけです。

「sqllocaldb.exestopv11.0」

「sqllocaldb.exedeletev11.0」

次回EFは、ファイルとデータベースを再生成します。

9
moranlf

アプリケーションのInitializeSimpleMembershipAttributeクラスを掘り下げると、それが継承するActionFilterAttributeクラスの次のオーバーライドされたメソッドが表示されます。

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

そのコメントに注意してください。アプリケーションは、実行ごとに1回チェックして、シンプルメンバーシップが適切に初期化されていることを確認します。クラスの上部にあるプライベート変数を見てください。

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

それらはすべて静的であり、すべて参照として渡されます。ここであなたの状況にとって重要なのは_isInitializedです。 LazyInitializer.EnsureInitializedが行うことは、_isInitializedフラグをチェックし、それがfalseの場合、渡されたrefターゲット、この場合はタイプSimpleMembershipInitializer_initializerを初期化します。その時点で、フラグをtrueに設定し、次に進みます。 LazyInitializer.EnsureInitializedがフラグが真であることを確認すると、ターゲットを返すだけです。そのフラグは静的変数であるため、アプリケーションの存続期間中その値を保持します。つまり、最初の初期化の後、EnsureInitializedは、データベースファイルが存在しなくなった場合でも、常にターゲットを返すだけです。つまり、初期化後に.mdfファイルを削除すると、アプリケーションは認識せず、アプリがデータベースからの読み取りまたは書き込みを試行したときに例外がスローされます。これを解決するには、アプリケーションを再起動する必要があります。つまり、使用している場合は開発サーバーを強制終了するか、IISでアプリケーションを再起動します。

これがあなたが直面している問題ですが、この質問に出くわした多くの人々は、ログインしようとしたときにこれと同様のエラーメッセージを受け取るという同様の異なる問題を抱えていると思います。

物理ファイル 'C:\ path\to\your\project\App_Data\dbfile.mdf'を開こうとしたとき、または作成しようとしたときに、CREATE FILEでオペレーティングシステムエラー5(アクセスが拒否されました)が発生しました。 CREATEDATABASEが失敗しました。リストされている一部のファイル名を作成できませんでした。関連するエラーを確認してください。

これは非常に簡単に解決できます。ここでも簡単に説明します。

デフォルトでは、Visual Studio 2012は、LocalDBと呼ばれるSQL ServerExpressの簡素化されたバージョンを使用します。 LocalDBは、アプリケーションの子プロセスを起動します。VisualStudioの開発サーバーでアプリケーションを実行している場合(たとえば、http:// localhost:[port]はブラウザーに表示されます)、両方のアプリケーションを実行しています。およびLocalDBは、SYSTEMまたはNETWORKSERVICEではなく、ユーザーアカウントの下にあります。これを修正するために必要なのは、プロジェクトのApp_Dataフォルダーの変更アクセス許可をユーザーに割り当てることだけです。ログインを再試行すると、.mdfファイルが正常に作成されます。

興味があれば、LocalDBについてもっと学ぶことができます ここ。

4
joelmdev

次のように、プロジェクトのルートフォルダーにあるGlobal.asaxファイルのApplication_Startメソッドでコードファーストデータベースの初期化を処理できます。

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

SetInitializerにnullを渡しても、データベーステーブルは作成または変更されないため、手動で行う必要があります。

データベースが再生成されない理由は、Application_Startがアプリケーションの存続期間中に1回だけ起動されるためです。

2
Mohsen Afshin

MVCで生成されたコードは、「DefaultConnection」という名前のデータベース接続文字列で機能します。 Web.configで別の名前を使用した場合は、次の場所でこの名前を参照する必要があります。

  1. InitializeSimpleMembershipAttribute.csのInitializeSimpleMembershipAttribute.SimpleMembershipInitializer.ctor()。
  2. AccountModel.csのUsersContext.ctor()

(または、プロジェクトで「DefaultConnection」を検索してください)。

2
ury

自動作成された.mdfファイルは、SQL管理ツールまたはオブジェクトエクスプローラーでのみ、エクスプローラーで削除しないでください。

あなたが得ている(そしてあなたが提供したステップで複製できる)問題は、データベースがまだLocalDbに登録されているということです。

1
Evonet

IISExpressインスタンスを停止し、再起動する必要があります(Visual StudioでF5キーを押します)。その後、データベースを再度作成できるようになります。

0
Will Huang

このエラーが発生したときに修正されたのは、VSプロジェクトのApp.configファイルの接続文字列を変更したことです。

これを接続文字列に追加しました:

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

これが他の誰かに役立つことを願っています。

0