spe*_*der 43 c# entity-framework ef-code-first entity-framework-4.3 dbmigrator
我们在SCM下有一个项目.当我从我的机器构建它并通过msdeploy发布到远程服务器时,一切正常.
当我的同事用同一个项目尝试相同的事情时,从SCM新推出,在远程服务器实体框架4.3.1上DbMigrator抛出:
未应用自动迁移,因为它会导致数据丢失.
事实证明,初始发布到远程服务器的人似乎是"赢家".如果我们将数据库放在远程服务器上,那么我的同事可以发布并且我被锁定了.我的出版物导致上述相同的错误.
配置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()
};
Run Code Online (Sandbox Code Playgroud)
我认为这与新表__MigrationHistory和存储在其行中的令人讨厌的长十六进制字符串有关.
我不想对出版生活承担全部责任.我能指出什么?
我们更改了代码:
dbMgConfig.AutomaticMigrationDataLossAllowed = false;
var mg = new DbMigrator(dbMgConfig);
mg.Update(null);
Run Code Online (Sandbox Code Playgroud)
至
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);
Run Code Online (Sandbox Code Playgroud)
这样我们就可以观察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')
Run Code Online (Sandbox Code Playgroud)
可以看出,DbMigrator抛出的原因是因为它试图通过反转它们桥接的表的名称(例如,GalleryImages到ImageGalleries或UserLightboxes来)来重命名3个用于连接many2many关系的表LightboxUsers.
这看起来像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");
});
}
Run Code Online (Sandbox Code Playgroud)
有了这个,错误现在就消失了.
| 归档时间: |
|
| 查看次数: |
9657 次 |
| 最近记录: |