web-dev-qa-db-ja.com

Entity Frameworkのコードファースト:更新データベースで移行が失敗し、不要な(?)追加移行が強制される

移行(EF 5.0)とコードファーストを使用して面白い効果があります。

GUID主キーを使用していくつかのモデルを作成しました。 (ところで:SQL ServerはNEWSEQUENTIALID()を使用することが重要です。これは現在のバージョンではデフォルト値のようです)

ある時点で、移行をアクティブにしました。最初の移行にいくつかのコードを追加しました。これは主に必要に応じて.Index()です。

データベースを削除してupdate-databaseを呼び出すと、次のエラーが表示されます。

保留中の変更があり、自動移行が無効になっているため、現在のモデルに一致するようにデータベースを更新できません。保留中のモデルの変更をコードベースの移行に書き込むか、自動移行を有効にします。 DbMigrationsConfiguration.AutomaticMigrationsEnabledをtrueに設定して、自動移行を有効にします。 Add-Migrationコマンドを使用して、保留中のモデルの変更をコードベースの移行に書き込むことができます。

AutomaticMigrationsEnabled = trueを試してみましたが、変更も追加もせずに機能しました。

しかし、AutomaticMigrationsEnabledは必要ないので、update-databaseに続いてadd-migrationと呼ばれるデータベースを再度削除しようとしました。最終的には、何も変更しないように思われる追加の移行が行われました(以下を参照)。また、これらの行を最初の移行の最後に追加しようとしましたが、これは何も変更しません。

モデルの1つ:

[Table(Speaker.TABLENAME)]
public class Speaker : BaseModel
{
    public const String TABLENAME = "Speaker";

    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }

    [Required]
    [MaxLength(50, ErrorMessage = "Name must be 50 characters or less")]
    public string Name { get; set; }
}

初期移行コード:

public partial class InitialCreate : DbMigration
{
    public override void Up()
    {
        // [...]
        CreateTable(
            "dbo.Speaker",
            c => new
                {
                    Id = c.Guid(nullable: false, identity: true),
                    Name = c.String(nullable: false, maxLength: 50),
                })
            .PrimaryKey(t => t.Id)
            .Index(t => t.Name, true, false);   // added manually: unique Name
        // [...]
    }
}

internal sealed class Configuration : DbMigrationsConfiguration<MyProject.Repositories.DBContext>
{
    public Configuration()
    {
        AutomaticMigrationsEnabled = false;
    }

    protected override void Seed(MyProject.Repositories.DBContext context)
    {
        // ...
    }
}

以下は、add-migrationによって作成されたコードです。新しいことは何もしないようです-何かが足りないのでしょうか?

public partial class UnneccessaryMigration : DbMigration
{
    public override void Up()
    {
        // isn't this the exact same code from InitialMigrations?
        AlterColumn("dbo.Speaker", "Id", c => c.Guid(nullable: false, identity: true));
        // ...
    }

    public override void Down()
    {
        //...
        AlterColumn("dbo.Speaker", "Id", c => c.Guid(nullable: false));
    }
}

だから私は興味があります:移行の見当識を失わせるために私は何をしましたか?そして、1回の初期移行で機能させるにはどうすればよいですか?

Solution:次の回避策は私のためにそれをしました:

  1. ここに記載されているように、データベースとすべての移行を削除しました: https://stackoverflow.com/a/11679386/3168401
  2. 実行されたEnable-Migrations + Add-Migration Initial
  3. 手作りの.Index()の変更をファイルにマージしました。データベースを削除するときに、Update-Databaseが再び機能するようになりました。
64
Its-me

また、update-databaseと呼ばれるデータベースを再度削除してから、移行を追加しようとしました。最終的には、何も変更しないように見える追加の移行が行われました(以下を参照)

上記の詳細に基づいて、私はあなたが最初に最後のことをしたと思います。 Update databaseの前にAdd-migrationを実行すると、移行スキーマでデータベースが更新されません。最初に移行を追加してから、更新コマンドを実行する必要があります。

パッケージマネージャーコンソールを使用して、この順序で試してください。

PM> Enable-migrations //You don't need this as you have already done it
PM> Add-migration Give_it_a_name
PM> Update-database
99
Kaf

Entity Frameworkには、IDフィールドに関するいくつかの問題があります。

既存のテーブルにGUID IDを追加することはできません

移行:DatabaseGeneratedOptionへの変更を検出しません

リバースエンジニアリングはGUIDキーをデフォルトのNEWSEQUENTIALID()でストア生成IDとしてマークしません

これらのいずれも問題を正確に説明しておらず、追加の移行のDown()メソッドは興味深いです。初期移行のCREATE TABLEが設定するように見えるときに列からIDENTITYを削除しようとするためです。

さらに、Update-Database -ScriptまたはUpdate-Database -Verboseを使用してこれらのAlterColumnメソッドから実行されるsqlを表示すると、UpDownでSQLが同一であり、実際には何も実行されないことがわかります。 IDの変更はありません(現在のバージョン-EF 6.0.2以下)-私がリンクした最初の2つの問題で説明されています。

余分な移行で冗長なコードを削除し、今のところは空の移行で生きる必要があると思います。また、対処する問題にサブスクライブ/投票することもできます。

参照:

IDENTITYオプションを変更するとしゃがみます

カスタム移行操作によるアイデンティティのオン/オフ切り替え

9
Colin

これを試して:

PM> Enable-migrations -force
PM> Add-migration MigrationName
PM> Update-database -force
2
Muhammad Awais

私にとっては、Visual Studio 2015で次のように解決しました:[表示]メニューから[他のウィンドウ]をクリックし、[パッケージマネージャーコンソール]をクリックして、次のコマンドを実行します:

PM> enable-migrations

プロジェクト 'mvcproject'で既に移行が有効になっています。既存の移行構成を上書きするには、-Forceパラメーターを使用します。

PM> enable-migrations -Force

コンテキストが既存のデータベースをターゲットにしているかどうかを確認しています...プロジェクトmvcprojectで有効なCode First Migrations。

次に、移行フォルダーの下に移行名を追加します。次のコマンドを実行して、ソリューションエクスプローラーに必要なクラスを追加します。

PM>Add-migration AddColumnUser

最後にデータベースを更新します

PM> update-database 
1
Abdullah

VS2019、MVC5を使用する場合-ファイルConfiguration.csのMigrationsフォルダーの下を見て編集します。AutomaticMigrationsEnabled= true

    -
0
Sam Patirage