gpt4 book ai didi

c# - Code first DbMigrator 在从不同机器构建时导致错误

转载 作者:IT王子 更新时间:2023-10-29 03:54:56 24 4
gpt4 key购买 nike

我们在 SCM 下有一个项目。当我从我的机器构建它并通过 msdeploy 发布到远程服务器时,一切正常。

当我的同事在远程服务器 Entity Framework 4.3.1 DbMigrator 上尝试对刚从 SCM 中提取的同一个项目进行相同的操作时,抛出:

Automatic migration was not applied because it would result in data loss.

事实证明,向远程服务器进行初始发布的人似乎是“赢家”。如果我们将数据库放在远程服务器上,那么我的同事可以发布,而我会被锁定。我的出版物导致了上述相同的错误。

DbMigrator 的配置如下所示:

        var dbMgConfig = new DbMigrationsConfiguration()
{
AutomaticMigrationsEnabled = true,
//***DO NOT REMOVE THIS LINE,
//DATA WILL BE LOST ON A BREAKING SCHEMA CHANGE,
//TALK TO OTHER PARTIES INVOLVED IF THIS LINE IS CAUSING PROBLEMS
AutomaticMigrationDataLossAllowed=false,
//***DO NOT REMOVE THIS LINE,
ContextType = typeof(TPSContext),
MigrationsNamespace = "TPS.Migrations",
MigrationsAssembly = Assembly.GetExecutingAssembly()
};

我认为这与新表 __MigrationHistory 和存储在其行中的看起来令人讨厌的长十六进制字符串有关。

我不想为发布生活承担全部责任。我需要注意什么?

最佳答案

我们更改了我们的代码:

        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 抛出的原因是因为它试图重命名 3 个用于连接多对多关系的表,方法是反转它们桥接的表的名称,例如 GalleryImagesImageGalleriesUserLightboxesLightboxUsers

解决方法

这看起来像是 EF 4.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");
});
}

有了这个,错误现在就消失了。

关于c# - Code first DbMigrator 在从不同机器构建时导致错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9516341/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com