既存のデータベースでEntity Framework 4.3を使用しており、いくつかのシナリオに対応しようとしています。
最初に、データベースを削除する場合、最初からEFを再作成します-これにCreateDatabaseIfNotExistsデータベース初期化子を正常に使用しました。
第二に、モデルを更新し、データベースが既に存在する場合、データベースを自動的に更新したいです-これにEntity Framework 4.3 Migrationsを使用しました。
だからここに私の質問です。いくつかの参照データを必要とするモデルに新しいテーブルを追加するとします。これは、データベースイニシャライザの実行時と移行の実行時の両方でこのデータを作成するための最良の方法です。私の望みは、データベースを最初から作成するとき、および移行の実行の結果としてデータベースが更新されるときにデータが作成されることです。
いくつかのEF移行の例では、人々は移行のUPメソッドでSQL()関数を使用してシードデータを作成しましたが、可能であればコンテキストを使用してシードデータを作成します(ほとんどのデータベース初期化の例で見られるように) EFの概念全体がそれを抽象化するときに純粋なSQLを使用するのは私には奇妙に思えます。 UPメソッドでコンテキストを使用しようとしましたが、何らかの理由で、テーブルを作成する呼び出しの直下にシードデータを追加しようとしたときに、移行で作成されたテーブルが存在するとは思われませんでした。
どんな知恵も大歓迎です。
エンティティを使用してデータをシードする場合は、移行構成でSeed
メソッドを使用する必要があります。新しいプロジェクトを生成する場合Enable-Migrations
この構成クラスを取得します。
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" }
// );
//
}
}
マイグレーションがデータをシードする方法は、非常に基本的なシードに使用されることになっているため、あまり効率的ではありません。新しいバージョンへのすべての更新は、セット全体を通過し、既存のデータの更新または新しいデータの挿入を試みます。 AddOrUpdate
拡張メソッドを使用しない場合、データがまだ存在しない場合にのみ、データがデータベースにシードされることを手動で確認する必要があります。
大量のデータをシードする必要があるため、効率的なシード方法が必要な場合は、commonでより良い結果が得られます。
public partial class SomeMigration : DbMigration
{
public override void Up()
{
...
Sql("UPDATE ...");
Sql("INSERT ...");
}
public override void Down()
{
...
}
}
Sql()
メソッドでUp()
呼び出しを使用することはお勧めしません。なぜなら、(IMO)これは実際には、シードコードではなく、組み込み関数がない実際の移行コードを対象としているからです。 。
シードデータは将来(スキーマが変更されない場合でも)変更される可能性があると考えているため、シード関数内のすべての挿入の周りに「ディフェンシブ」チェックを記述して、操作が実行されないことを確認します以前。
3つのエントリで始まる「タイプ」テーブルがあり、その後4番目を追加するシナリオを考えます。これに対処するために「移行」は必要ありません。
Seed()
を使用すると、操作する完全なコンテキストも得られます。これは、Ladislavが示したSql()
メソッドでプレーンなsql文字列を使用するよりもはるかに優れています。
また、移行コードとシードコードの両方に組み込みEFメソッドを使用する利点は、データベース操作がプラットフォームに依存しないことです。これは、スキーマの変更とクエリをOracle、Postgreなどで実行できることを意味します。実際の生のSQLを記述する場合、不必要に自分をロックしてしまう可能性があります。
EFを使用している人の90%がSQL Serverにしかヒットしないため、これについてはあまり気にしないかもしれませんが、ソリューションについては別の見方をするためにそこに投げています。