私のMVCアプリケーションでは、Entity Framework 6を使用し、コードファーストアプローチでデータベースを作成しました。しばらくして、新しい列を追加し、いくつかの列を削除して、エンティティクラスの1つを更新しました。私は以下の手順に従ったデータベースにこれらの変更を反映するための:
- プロジェクト内のフォルダの移行を削除しました。
- データベースの__MigrationHistoryテーブルを削除しました。
そして、パッケージマネージャコンソールで次のコマンドを実行します。
Enable-Migrations -EnableAutomaticMigrations -Force構成ファイルに次の行を追加します。
AutomaticMigrationsEnabled = true;
AutomaticMigrationDataLossAllowed = true;実行:
Add-Migration Initial- そして最後に、実行します。
pdate-Database -Verbose
ただし、エラーが発生します「データベースにはすでに「xxx」という名前のオブジェクトがあります。」
この問題を取り除くために、5番目のステップの後に作成された初期ファイルのUpメソッドのコードにコメントを付けます。これによりエラーは防止されますが、データベースでは何も変更されません(更新されたエンティティテーブルは以前と同じままです)。間違いはどこですか?あなたの助けを事前に感謝します。
これが、migration.csファイルでコメントしたUpメソッドです:
public override void Up()
{
CreateTable(
"dbo.City",
c => new
{
ID = c.Int(nullable: false, identity: true),
Name = c.String(nullable: false),
RegionID = c.Int(nullable: false),
})
.PrimaryKey(t => t.ID)
.ForeignKey("dbo.Region", t => t.RegionID)
.Index(t => t.RegionID);
CreateTable(
"dbo.Multiplier",
c => new
{
ID = c.Int(nullable: false, identity: true),
Status = c.Int(nullable: false),
Term = c.Int(nullable: false),
CityID = c.Int(nullable: false),
WhoIsOnline = c.String(nullable: false),
UserId = c.String(nullable: false),
InstituteName = c.String(nullable: false),
InstituteStatusID = c.Int(nullable: false),
InstituteAccreditationDate = c.DateTime(nullable: false),
Address = c.String(nullable: false),
Phone = c.String(nullable: false),
Fax = c.String(),
Email = c.String(nullable: false),
EurodeskEmail = c.String(nullable: false),
WebSite = c.String(),
ContactName = c.String(nullable: false),
ContactSurname = c.String(nullable: false),
ContactJobTitle = c.String(),
ContactAssignmentDate = c.DateTime(),
ContactWorkingStart = c.String(),
ContactWorkingkEnd = c.String(),
ContactPhone = c.String(),
ContactMobile = c.String(nullable: false),
ContactEmail = c.String(nullable: false),
ContactCityID = c.Int(nullable: false),
LegalRepresentativeName = c.String(nullable: false),
LegalRepresentativeSurname = c.String(nullable: false),
})
.PrimaryKey(t => t.ID)
.ForeignKey("dbo.City", t => t.CityID)
.ForeignKey("dbo.InstituteStatus", t => t.InstituteStatusID)
.Index(t => t.CityID)
.Index(t => t.InstituteStatusID);
CreateTable(
"dbo.InstituteStatus",
c => new
{
ID = c.Int(nullable: false, identity: true),
Name = c.String(nullable: false),
})
.PrimaryKey(t => t.ID);
CreateTable(
"dbo.TrainingParticipant",
c => new
{
ID = c.Int(nullable: false, identity: true),
TrainingID = c.Int(nullable: false),
ParticipantID = c.Int(nullable: false),
Multiplier_ID = c.Int(),
})
.PrimaryKey(t => t.ID)
.ForeignKey("dbo.Participant", t => t.ParticipantID)
.ForeignKey("dbo.Training", t => t.TrainingID)
.ForeignKey("dbo.Multiplier", t => t.Multiplier_ID)
.Index(t => t.TrainingID)
.Index(t => t.ParticipantID)
.Index(t => t.Multiplier_ID);
CreateTable(
"dbo.Participant",
c => new
{
ID = c.Int(nullable: false, identity: true),
Name = c.String(nullable: false),
Surname = c.String(nullable: false),
MultiplierID = c.Int(nullable: false),
})
.PrimaryKey(t => t.ID)
.ForeignKey("dbo.Multiplier", t => t.MultiplierID)
.Index(t => t.MultiplierID);
CreateTable(
"dbo.Training",
c => new
{
ID = c.Int(nullable: false, identity: true),
Name = c.String(nullable: false),
Date = c.DateTime(nullable: false),
CityID = c.Int(nullable: false),
})
.PrimaryKey(t => t.ID)
.ForeignKey("dbo.City", t => t.CityID)
.Index(t => t.CityID);
CreateTable(
"dbo.Region",
c => new
{
ID = c.Int(nullable: false, identity: true),
Name = c.String(nullable: false),
})
.PrimaryKey(t => t.ID);
}
そしてこれはmigration.csファイルのDownメソッドです:
public override void Down()
{
DropForeignKey("dbo.City", "RegionID", "dbo.Region");
DropForeignKey("dbo.TrainingParticipant", "Multiplier_ID", "dbo.Multiplier");
DropForeignKey("dbo.TrainingParticipant", "TrainingID", "dbo.Training");
DropForeignKey("dbo.Training", "CityID", "dbo.City");
DropForeignKey("dbo.TrainingParticipant", "ParticipantID", "dbo.Participant");
DropForeignKey("dbo.Participant", "MultiplierID", "dbo.Multiplier");
DropForeignKey("dbo.Multiplier", "InstituteStatusID", "dbo.InstituteStatus");
DropForeignKey("dbo.Multiplier", "CityID", "dbo.City");
DropIndex("dbo.Training", new[] { "CityID" });
DropIndex("dbo.Participant", new[] { "MultiplierID" });
DropIndex("dbo.TrainingParticipant", new[] { "Multiplier_ID" });
DropIndex("dbo.TrainingParticipant", new[] { "ParticipantID" });
DropIndex("dbo.TrainingParticipant", new[] { "TrainingID" });
DropIndex("dbo.Multiplier", new[] { "InstituteStatusID" });
DropIndex("dbo.Multiplier", new[] { "CityID" });
DropIndex("dbo.City", new[] { "RegionID" });
DropTable("dbo.Region");
DropTable("dbo.Training");
DropTable("dbo.Participant");
DropTable("dbo.TrainingParticipant");
DropTable("dbo.InstituteStatus");
DropTable("dbo.Multiplier");
DropTable("dbo.City");
}
なぜステップ1〜4を実行したのですか?それはあなたが間違っていたところです。以前に生成されたデータベースがあり、スキーマに変更を加えるだけの場合は、移行を生成して適用するだけです。手順1〜4を実行することで、このデータベースに関するEntity Frameworkの知識を効果的に元に戻し、基本的に既存のデータベースでコードファーストになります。その時点で、スキーマを手動で変更するか、EntityFrameworkにスキーマを吹き飛ばして最初からやり直す必要があります。
移行を再度適用できる状態に戻る限り、移行を生成し、Up
メソッドを空にするだけで正しい方向に進んでいました。ただし、これは、アプリケーションの以前の状態、つまり現在のデータベースと一致する状態に対して行う必要があります。それ以外の場合、Entity Frameworkは、コードの変更を含む作成テーブルを生成します。したがって、従う手順は次のとおりです。
Up
メソッドのすべてを削除しますupdate-database
を使用して移行を適用しますその後、また行ってもいいはずです。次に、コードを変更するときは、手順5と6に従ってください。
私はこの正確な問題を抱えています。この状況を支援するコマンド、つまり-IgnoreChangesフラグと-Forceフラグが用意されていることは注目に値します。
マルチdbContextからシングルdbContextアプリにトリミングしていました。ご想像のとおり、テーブルはすでに存在していましたが、単一のコンテキストでは、2番目のコンテキストで維持されていたテーブルはまったく新しいものではありません。
それは実際には非常に単純です(役に立たないという答えを2日間検索した結果、 EF Code First Migrationsとパッケージマネージャーのコマンドライン ...)を読むことになりました。それを処理しました。
SQLで移行フォルダと_Migrationsテーブルを削除できます…これにより、次を使用する必要があります:Enable-Migrations -Force
しかし、抜本的な対策を講じることなく、ここからピックアップできるはずです。
これで、追加のフラグなしでAdd-MigrationとUpdate-Databaseを使用するだけで軌道に戻るはずです。