質問

最新のEFコードFirst Nugetパッケージには、のカスタム実装が付属しています IDatabaseInitializer 呼び出されました DontDropDbJustCreateTablesIfModelChanged. 。名前が示すように、モデルの変更が検出された場合、データベース全体をドロップして再作成することはなく、テーブルをドロップして再現するだけです。

私はこのモデルクラスを持っているとします:

public class User
{
    public string Username { get; set; }

    // This property is new; the model has changed!
    public string OpenID { get; set; }
}

どのように実装しますか IDatabaseInitializer それ テーブルもドロップしません. 。この場合、それはただ追加します OpenID ユーザーテーブルへの列?

役に立ちましたか?

解決

SQLの問題だと思います。したがって、SQL Serverの場合は次のようなものを書くことができます。

public class MyInitializer : IDatabaseInitializer<MyContext>
{
    public void InitializeDatabase(MyContext context)
    {
        context.Database.SqlCommand(
            @"
            IF NOT EXISTS (SELECT 1 FROM sys.columns AS col
                           INNER JOIN sys.tables AS tab ON tab.object_Id = col.object_Id
                           WHERE tab.Name = 'User' AND col.Name = 'OpenId')
            BEGIN
                ALTER TABLE dbo.User ADD OpenId INT; 
            END");
    }
}

しかし、同じように、そのようなスクリプトをアプリケーションに追加せずに実行することができます。

他のヒント

最初にCodeの現在のバージョンを使用すると、スキーマを修正してテーブルにあるデータを保存することはできません。このリリースで参照データ /ルックアップテーブルなどのデータを維持することが重要である場合、独自の初期イザーを作成し、シードメソッドをオーバーライドしてテーブルを入力できます。

public class MyDbInitializer : DropCreateDatabaseIfModelChanges<MyContext>
{
    protected override void Seed(MyContext context)
    {
        var countries = new List<Country>
        {
            new Country {Id=1, Name="United Kingdom"},
            new Country{Id=2, Name="Ireland"}
        };

        countries.ForEach(c => context.Countries.Add(c));
    }
}

そして、これをapplication_startで使用します。

Database.SetInitializer<MyContext>(new MyDbInitializer());

これは現在EFチームによって対処されていると思いますが、コードの最初のドロップが発表された時点ではリリースの準備ができていませんでした。ここでプレビューを見ることができます: 最初の移行をコードします

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top