43

SCMの下にプロジェクトがあります。自分のマシンからビルドし、msdeployを介してリモートサーバーに公開すると、すべてが正常に機能します。

私の同僚が、リモートサーバーエンティティフレームワーク4.3.1で、SCMから新たにプルされた同じプロジェクトで同じことを試みると、次のようになります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()
        };

__MigrationHistoryこれは、新しいテーブルと、その行に格納されている厄介な長い16進文字列と関係があると思います。

私は、出版するために全責任を負いたくありません。何に気をつければいいですか?

4

5 に答える 5

8

コードを次のように変更しました。

        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");
            });
    }

これが適切な場所にあると、エラーはなくなります。

于 2012-07-09T15:35:06.987 に答える
2
 public Configuration()
        {
            AutomaticMigrationsEnabled = true;
            AutomaticMigrationDataLossAllowed = true;
        } 
于 2013-04-23T21:07:13.460 に答える
1

同じエラーが発生するので、スクリプトを生成してクエリアナライザーで実行しました。それは鍵長の問題であることが判明しました:

警告!キーの最大長は900バイトです。インデックス'PK_dbo.__MigrationHistory'の最大長は1534バイトです。大きな値の組み合わせによっては、挿入/更新操作が失敗します。

EntityFrameworkチームがそれを認識しているようです。

http://entityframework.codeplex.com/workitem/1216

これがどのような問題を引き起こすのかわからない.....

于 2013-08-20T18:57:59.773 に答える
0

私もこの問題に遭遇しました。奇妙なことに、問題のテーブルにはデータがまったく含まれていません。つまり、空です。これは、移行を適用した場合にデータ損失が発生することを報告するときに、CodeFirstがチェックしていないようです。

于 2013-08-09T21:10:48.770 に答える
0

EntityFramework6.2.0でこれに似た本当に奇妙なエラーが発生しました。

Configuration.cs:

public class Configuration : DbMigrationsConfiguration<ApplicationDbContext>
{
    public Configuration()
    {
        AutomaticMigrationsEnabled = false;
        AutomaticMigrationDataLossAllowed = false;
    }
...
}

以下のコードは、StackOverflowExceptionあるマシンではを引き起こしましたが、別のマシンでは正常に機能しました。

var migrator = new DbMigrator(new Configuration());
if (migrator.GetPendingMigrations().Any())
{
    migrator.Update();
}

代わりに次のようにアップグレードして解決しました。

Database.SetInitializer(new MigrateDatabaseToLatestVersion<ApplicationDbContext, Configuration>());
于 2019-01-22T14:53:48.453 に答える