2012-02-18 10 views
41

私は既存のデータベースでEntity Framework 4.3を使用していましたが、私はそれに対応しようとしているいくつかのシナリオを持っています。Entity Framework 4.3で段階的にデータをシードする最善の方法

データベースを削除すると、最初からEFで再作成したいと思っています。これに対してCreateDatabaseIfNotExistsデータベースイニシャライザを使用しました。

第2に、モデルを更新してデータベースがすでに存在する場合、データベースを自動的に更新したいと思います。これに対して、Entity Framework 4.3 Migrationsを正常に使用しました。

ここに私の質問があります。私のモデルに、参照データが必要な新しいテーブルを追加するとします。これは、データベースの初期化ツールが実行されているときと、移行が実行されたときの両方で、このデータが確実に作成されるようにするためです。私の望みは、データベースをゼロから作成しているときにデータが作成され、移行が実行された結果としてデータベースが更新されるときです。

いくつかのEFの移行例では、移行のUPメソッドでSQL()関数を使用してシードデータを作成するのを見たことがありますが、可能であれば、シードデータを作成するためにデータベースの初期化の例)、EF全体のアイデアがそれを抽象化しているときに純粋なSQLを使用することは私には奇妙に思えるので、私はUPメソッドでコンテキストを使用しようとしましたが、何らかの理由で、テーブルを作成するための呼び出しのすぐ下にシードデータを追加しようとしたときに、移行で作成されたテーブルが存在しないと考えていませんでした。

どのような知恵にも大変感謝します。

答えて

53

エンティティを使用してデータをシードする場合は、移行設定でSeedメソッドを使用する必要があります。いくつかの非常に基本的な播種のために使用されることを想定しているため、移行シードデータは非常に効率的ではありませんか

internal sealed class Configuration : DbMigrationsConfiguration<YourContext> 
{ 
    public Configuration() 
    { 
     AutomaticMigrationsEnabled = false; 
    } 

    protected override void Seed(CFMigrationsWithNoMagic.BlogContext context) 
    { 
     // This method will be called after migrating to the latest version. 

     // You can use the DbSet<T>.AddOrUpdate() helper extension method 
     // to avoid creating duplicate seed data. E.g. 
     // 
     // context.People.AddOrUpdate(
     //  p => p.FullName, 
     //  new Person { FullName = "Andrew Peters" }, 
     //  new Person { FullName = "Brice Lambson" }, 
     //  new Person { FullName = "Rowan Miller" } 
     // ); 
     // 
    } 
} 

方法:あなたは、このコンフィギュレーション・クラスを取得しますEnable-Migrations新鮮なプロジェクトを生成する場合。新しいバージョンへの更新はすべてセット全体を通って進み、既存のデータを更新したり新しいデータを挿入しようとします。 AddOrUpdate拡張メソッドを使用しない場合、データがまだ存在していない場合にのみ、データがデータベースにシードされることを手動で確認する必要があります。

あなたはデータの入出力多くをシードする必要がありますので、あなたが播種のための効率的な方法をしたい場合は、一般的に、より良い結果を得るでしょうに:

public partial class SomeMigration : DbMigration 
{ 
    public override void Up() 
    { 
     ... 
     Sql("UPDATE ..."); 
     Sql("INSERT ..."); 
    } 

    public override void Down() 
    { 
     ... 
    } 
} 
+8

実際には、Upメソッドでコンテキストを作成し、AddOrUpdateを使用して行を挿入できます。ただし、これは移行トランザクションにラップされないため、問題を引き起こす可能性があります。また、モデルが変更されたときに将来コンパイルすることは保証されません。 – Betty

+0

Upメソッドでコンテキストを作成しようとしましたが、テーブルが存在しないというエラーが送出されました。代わりに、 "Up"メソッドでSQLを試してみます。 –

+8

@ラディスラフEFに関するあなたの深い知識は、私を驚かせ続けます。トピックに関する本の作成を検討し、ここで遭遇する一般的な誤解に対処することを考えましたか? – kingdango

32

私は(IMO)ので、あなたのUp()方法でSql()呼び出しを使用してお勧めしませんこれは実際にシードコードではなく組み込み関数がない実際のマイグレーションコードを対象としています。

私はシードデータを将来変更する可能性のあるものと思っています(スキーマがない場合でも)。そのため、シード関数内のすべての挿入を「守る」チェックを書くだけで、操作は以前には起動しませんでした。

「タイプ」テーブルが3つのエントリから始まり、後で4番目を追加するシナリオを考えてみましょう。これに対処するために「移行」は必要ありません。

Seed()を使用すると、Ladislavが実証したSql()メソッドのプレーンSQL文字列を使用するよりもはるかにいいです。

また、移行コードとシードコードの両方に組み込みEFメソッドを使用する利点は、データベース操作がプラットフォームに依存しないことです。これは、スキーマの変更やクエリがOracle、Postgreなどで実行できることを意味します。実際の未処理のSQLを記述すると、不必要に自分自身をロックする可能性があります。

EFを使用している人の90%がSQL Serverにぶつかりますので、これについてはあまり心配しないかもしれませんが、私は解決策について別の見解を得るためにそこに投げています。

+7

"Up"メソッドは "Reference"データを参照するのに適していると考えています。参照データとは、一般的にアプリケーションが何らかのロジックのためにそのデータを必要としていることを意味します。 – nootn

関連する問題