11

次のようなカスタム データベース初期化子で Entity Framework 4.3 Code First を使用しています。

public class MyContext : DbContext
{
    public MyContext()
    {
        Database.SetInitializer(new MyContextInitializer());
    }
}

public class MyContextInitializer : CreateDatabaseIfNotExists<MyContext>
{
    protected override void Seed(MyContext context)
    {
        // Add defaults to certain tables in the database

        base.Seed(context);
    }
}

モデルが変更されるたびに、POCO とマッピングを手動で編集し、データベースを手動で更新します。

アプリケーションを再度実行すると、次のエラーが発生します。

「/」アプリケーションでサーバー エラーが発生しました。

データベースが作成されてから、「MyContext」コンテキストをサポートするモデルが変更されました。Code First Migrations を使用してデータベースを更新することを検討してください (http://go.microsoft.com/fwlink/?LinkId=238269)。

説明:現在の Web 要求の実行中に未処理の例外が発生しました。エラーの詳細とコード内のどこでエラーが発生したかについては、スタック トレースを確認してください。

例外の詳細: System.InvalidOperationException: データベースが作成されてから、'MyContext' コンテキストをサポートするモデルが変更されました。Code First Migrations を使用してデータベースを更新することを検討してください (http://go.microsoft.com/fwlink/?LinkId=238269)。

EFProfiler を使用すると、次のクエリが実行されていることにも気付きます。

-- statement #1
SELECT [GroupBy1].[A1] AS [C1]
FROM   (SELECT COUNT(1) AS [A1]
        FROM   [dbo].[__MigrationHistory] AS [Extent1]) AS [GroupBy1]

-- statement #2
SELECT TOP (1) [Project1].[C1]          AS [C1],
               [Project1].[MigrationId] AS [MigrationId],
               [Project1].[Model]       AS [Model]
FROM   (SELECT [Extent1].[MigrationId] AS [MigrationId],
               [Extent1].[CreatedOn]   AS [CreatedOn],
               [Extent1].[Model]       AS [Model],
               1                       AS [C1]
        FROM   [dbo].[__MigrationHistory] AS [Extent1]) AS [Project1]
ORDER  BY [Project1].[CreatedOn] DESC

どうすればこれを防ぐことができますか?

4

2 に答える 2

10

最初は、ctor にデフォルトのイニシャライザを設定したことが原因だと確信していましたが、少し調べてみると、コンテキストが作成されたときにイニシャライザが実行されるのではなく、最初に何かをクエリまたは追加したときに実行されることがわかりました。

提供された初期化子はすべてモデルの互換性をチェックするため、運が悪いです。ただし、代わりに次のように独自の初期化子を簡単に作成できます。

 public class Initializer : IDatabaseInitializer<Context>
    {

        public void InitializeDatabase(Context context)
        {
            if (!context.Database.Exists())
            {
                context.Database.Create();
                Seed(context);
                context.SaveChanges();
            }
        }

        private void Seed(Context context)
        {
            throw new NotImplementedException();
        }
    }

それは互換性をチェックするべきではなく、データベースが見つからない場合はそれを作成します。

更新:「コンテキスト」は、DbContext の実装のタイプである必要があります

于 2012-06-29T09:53:46.507 に答える