コードを次のように変更しました。
dbMgConfig.AutomaticMigrationDataLossAllowed = false;
var mg = new DbMigrator(dbMgConfig);
mg.Update(null);
に
dbMgConfig.AutomaticMigrationDataLossAllowed = true;
var mg = new DbMigrator(dbMgConfig);
var scriptor = new MigratorScriptingDecorator(mg);
string script = scriptor.ScriptUpdate(sourceMigration: null, targetMigration: null);
throw new Exception(script);
DbMigrator
これにより、リモートサーバーでどのような変更が試行されているかを確認できます。
この質問の冒頭で概説した場合(つまり、同僚がデータベースを作成するアップロードを行い、続いて私が別のマシンの同じソースからアップロードを生成する)、次のSQLステートメントが生成されます。
ALTER TABLE [GalleryImages] DROP CONSTRAINT [FK_GalleryImages_Galleries_Gallery_Id]
ALTER TABLE [GalleryImages] DROP CONSTRAINT [FK_GalleryImages_Images_Image_Id]
ALTER TABLE [UserLightboxes] DROP CONSTRAINT [FK_UserLightboxes_Users_User_Id]
ALTER TABLE [UserLightboxes] DROP CONSTRAINT [FK_UserLightboxes_Lightboxes_Lightbox_Id]
ALTER TABLE [ImageLightboxes] DROP CONSTRAINT [FK_ImageLightboxes_Images_Image_Id]
ALTER TABLE [ImageLightboxes] DROP CONSTRAINT [FK_ImageLightboxes_Lightboxes_Lightbox_Id]
DROP INDEX [IX_Gallery_Id] ON [GalleryImages]
DROP INDEX [IX_Image_Id] ON [GalleryImages]
DROP INDEX [IX_User_Id] ON [UserLightboxes]
DROP INDEX [IX_Lightbox_Id] ON [UserLightboxes]
DROP INDEX [IX_Image_Id] ON [ImageLightboxes]
DROP INDEX [IX_Lightbox_Id] ON [ImageLightboxes]
CREATE TABLE [ImageGalleries] (
[Image_Id] [int] NOT NULL,
[Gallery_Id] [int] NOT NULL,
CONSTRAINT [PK_ImageGalleries] PRIMARY KEY ([Image_Id], [Gallery_Id])
)
CREATE TABLE [LightboxImages] (
[Lightbox_Id] [int] NOT NULL,
[Image_Id] [int] NOT NULL,
CONSTRAINT [PK_LightboxImages] PRIMARY KEY ([Lightbox_Id], [Image_Id])
)
CREATE TABLE [LightboxUsers] (
[Lightbox_Id] [int] NOT NULL,
[User_Id] [int] NOT NULL,
CONSTRAINT [PK_LightboxUsers] PRIMARY KEY ([Lightbox_Id], [User_Id])
)
CREATE INDEX [IX_Image_Id] ON [ImageGalleries]([Image_Id])
CREATE INDEX [IX_Gallery_Id] ON [ImageGalleries]([Gallery_Id])
CREATE INDEX [IX_Lightbox_Id] ON [LightboxImages]([Lightbox_Id])
CREATE INDEX [IX_Image_Id] ON [LightboxImages]([Image_Id])
CREATE INDEX [IX_Lightbox_Id] ON [LightboxUsers]([Lightbox_Id])
CREATE INDEX [IX_User_Id] ON [LightboxUsers]([User_Id])
DROP TABLE [GalleryImages]
DROP TABLE [UserLightboxes]
DROP TABLE [ImageLightboxes]
ALTER TABLE [ImageGalleries] ADD CONSTRAINT [FK_ImageGalleries_Images_Image_Id] FOREIGN KEY ([Image_Id]) REFERENCES [Images] ([Id]) ON DELETE CASCADE
ALTER TABLE [ImageGalleries] ADD CONSTRAINT [FK_ImageGalleries_Galleries_Gallery_Id] FOREIGN KEY ([Gallery_Id]) REFERENCES [Galleries] ([Id]) ON DELETE CASCADE
ALTER TABLE [LightboxImages] ADD CONSTRAINT [FK_LightboxImages_Lightboxes_Lightbox_Id] FOREIGN KEY ([Lightbox_Id]) REFERENCES [Lightboxes] ([Id]) ON DELETE CASCADE
ALTER TABLE [LightboxImages] ADD CONSTRAINT [FK_LightboxImages_Images_Image_Id] FOREIGN KEY ([Image_Id]) REFERENCES [Images] ([Id]) ON DELETE CASCADE
ALTER TABLE [LightboxUsers] ADD CONSTRAINT [FK_LightboxUsers_Lightboxes_Lightbox_Id] FOREIGN KEY ([Lightbox_Id]) REFERENCES [Lightboxes] ([Id]) ON DELETE CASCADE
ALTER TABLE [LightboxUsers] ADD CONSTRAINT [FK_LightboxUsers_Users_User_Id] FOREIGN KEY ([User_Id]) REFERENCES [Users] ([Id]) ON DELETE CASCADE
CREATE TABLE [__MigrationHistory] (
[MigrationId] [nvarchar](255) NOT NULL,
[CreatedOn] [datetime] NOT NULL,
[Model] [varbinary](max) NOT NULL,
[ProductVersion] [nvarchar](32) NOT NULL,
CONSTRAINT [PK___MigrationHistory] PRIMARY KEY ([MigrationId])
)
BEGIN TRY
EXEC sp_MS_marksystemobject '__MigrationHistory'
END TRY
BEGIN CATCH
END CATCH
INSERT INTO [__MigrationHistory] ([MigrationId], [CreatedOn], [Model], [ProductVersion]) VALUES ('201203030113082_AutomaticMigration', '2012-03-03T01:13:08.986Z', 0x[removedToShortenPost], '4.3.1')
ご覧のとおり、スローする理由DbMigrator
は、ブリッジするテーブルの名前を逆にすることで、many2many関係を結合するために使用される3つのテーブルの名前を変更しようとしてGalleryImages
いるImageGalleries
ためUserLightboxes
ですLightboxUsers
。
回避策
これはEF4.3のバグのように見え、「関連付け」テーブルの名前の順序が不確定であるように見えます。これらの種類のテーブルの名前の順序は未定義/不確定であるように見えるため、流暢なAPIを使用して、EFにさまざまなマシンのビルド間で一貫した命名を使用させることで、別の角度からこれにアプローチしました。
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder
.Entity<Gallery>()
.HasMany(p => p.Images)
.WithMany(p => p.Galleries)
.Map(c =>
{
c.MapLeftKey("Gallery_Id");
c.MapRightKey("Image_Id");
c.ToTable("GalleryImages");
});
modelBuilder
.Entity<User>()
.HasMany(p => p.Lightboxes)
.WithMany(p => p.Users)
.Map(c =>
{
c.MapLeftKey("User_Id");
c.MapRightKey("Lightbox_Id");
c.ToTable("UserLightboxes");
});
modelBuilder
.Entity<Image>()
.HasMany(p => p.Lightboxes)
.WithMany(p => p.Images)
.Map(c =>
{
c.MapLeftKey("Image_Id");
c.MapRightKey("Lightbox_Id");
c.ToTable("ImageLightboxes");
});
}
これが適切な場所にあると、エラーはなくなります。