Update-DatabaseがPackage Managerコンソールから失敗しました。私はEntity Framework 6.xとコードファーストアプローチを使用しました。エラーは
"データベースに 'AboutUs'という名前のオブジェクトが既にあります。
どうすればこの問題を解決できますか?
internal sealed class Configuration
: DbMigrationsConfiguration<Jahan.Blog.Web.Mvc.Models.JahanBlogDbContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
AutomaticMigrationDataLossAllowed = false;
}
protected override void Seed(Jahan.Blog.Web.Mvc.Models.JahanBlogDbContext context)
{
}
}
私のDbContextは、
public class JahanBlogDbContext : IdentityDbContext<User, Role, int, UserLogin, UserRole, UserClaim>
{
public JahanBlogDbContext()
: base("name=JahanBlogDbConnectionString")
{
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<JahanBlogDbContext>());
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Entity<Comment>().HasRequired(t => t.Article).WithMany(t => t.Comments).HasForeignKey(d => d.ArticleId).WillCascadeOnDelete(true);
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<User>().ToTable("User");
modelBuilder.Entity<Role>().ToTable("Role");
modelBuilder.Entity<UserRole>().ToTable("UserRole");
modelBuilder.Entity<UserLogin>().ToTable("UserLogin");
modelBuilder.Entity<UserClaim>().ToTable("UserClaim");
}
public virtual DbSet<Article> Articles { get; set; }
public virtual DbSet<ArticleLike> ArticleLikes { get; set; }
public virtual DbSet<ArticleTag> ArticleTags { get; set; }
public virtual DbSet<AttachmentFile> AttachmentFiles { get; set; }
public virtual DbSet<Comment> Comments { get; set; }
public virtual DbSet<CommentLike> CommentLikes { get; set; }
public virtual DbSet<CommentReply> CommentReplies { get; set; }
public virtual DbSet<ContactUs> ContactUs { get; set; }
public virtual DbSet<Project> Projects { get; set; }
public virtual DbSet<ProjectState> ProjectStates { get; set; }
public virtual DbSet<ProjectTag> ProjectTags { get; set; }
public virtual DbSet<Rating> Ratings { get; set; }
public virtual DbSet<Tag> Tags { get; set; }
public virtual DbSet<AboutUs> AboutUs { get; set; }
}
パッケージ管理コンソール:
PM> update-database -verbose -force
Using StartUp project 'Jahan.Blog.Web.Mvc'.
Using NuGet project 'Jahan.Blog.Web.Mvc'.
Specify the '-Verbose' flag to view the SQL statements being applied to the target database.
Target database is: 'Jahan-Blog' (DataSource: (local), Provider: System.Data.SqlClient, Origin: Configuration).
No pending explicit migrations.
Applying automatic migration: 201410101740197_AutomaticMigration.
CREATE TABLE [dbo].[AboutUs] (
[Id] [int] NOT NULL IDENTITY,
[Description] [nvarchar](max),
[IsActive] [bit] NOT NULL,
[CreatedDate] [datetime],
[ModifiedDate] [datetime],
CONSTRAINT [PK_dbo.AboutUs] PRIMARY KEY ([Id])
)
System.Data.SqlClient.SqlException (0x80131904): There is already an object named 'AboutUs' in the database.
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
at System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async, Int32 timeout, Boolean asyncWrite)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite)
at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.<NonQuery>b__0(DbCommand t, DbCommandInterceptionContext`1 c)
at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed)
at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.NonQuery(DbCommand command, DbCommandInterceptionContext interceptionContext)
at System.Data.Entity.Internal.InterceptableDbCommand.ExecuteNonQuery()
at System.Data.Entity.Migrations.DbMigrator.ExecuteSql(DbTransaction transaction, MigrationStatement migrationStatement, DbInterceptionContext interceptionContext)
at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.ExecuteSql(DbTransaction transaction, MigrationStatement migrationStatement, DbInterceptionContext interceptionContext)
at System.Data.Entity.Migrations.DbMigrator.ExecuteStatementsInternal(IEnumerable`1 migrationStatements, DbTransaction transaction, DbInterceptionContext interceptionContext)
at System.Data.Entity.Migrations.DbMigrator.ExecuteStatementsInternal(IEnumerable`1 migrationStatements, DbConnection connection)
at System.Data.Entity.Migrations.DbMigrator.<>c__DisplayClass30.<ExecuteStatements>b__2e()
at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.<>c__DisplayClass1.<Execute>b__0()
at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation)
at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute(Action operation)
at System.Data.Entity.Migrations.DbMigrator.ExecuteStatements(IEnumerable`1 migrationStatements, DbTransaction existingTransaction)
at System.Data.Entity.Migrations.DbMigrator.ExecuteStatements(IEnumerable`1 migrationStatements)
at System.Data.Entity.Migrations.Infrastructure.MigratorBase.ExecuteStatements(IEnumerable`1 migrationStatements)
at System.Data.Entity.Migrations.DbMigrator.ExecuteOperations(String migrationId, XDocument targetModel, IEnumerable`1 operations, IEnumerable`1 systemOperations, Boolean downgrading, Boolean auto)
at System.Data.Entity.Migrations.DbMigrator.AutoMigrate(String migrationId, VersionedModel sourceModel, VersionedModel targetModel, Boolean downgrading)
at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.AutoMigrate(String migrationId, VersionedModel sourceModel, VersionedModel targetModel, Boolean downgrading)
at System.Data.Entity.Migrations.DbMigrator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
at System.Data.Entity.Migrations.DbMigrator.UpdateInternal(String targetMigration)
at System.Data.Entity.Migrations.DbMigrator.<>c__DisplayClassc.<Update>b__b()
at System.Data.Entity.Migrations.DbMigrator.EnsureDatabaseExists(Action mustSucceedToKeepDatabase)
at System.Data.Entity.Migrations.Infrastructure.MigratorBase.EnsureDatabaseExists(Action mustSucceedToKeepDatabase)
at System.Data.Entity.Migrations.DbMigrator.Update(String targetMigration)
at System.Data.Entity.Migrations.Infrastructure.MigratorBase.Update(String targetMigration)
at System.Data.Entity.Migrations.Design.ToolingFacade.UpdateRunner.Run()
at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
at System.Data.Entity.Migrations.Design.ToolingFacade.Run(BaseRunner runner)
at System.Data.Entity.Migrations.Design.ToolingFacade.Update(String targetMigration, Boolean force)
at System.Data.Entity.Migrations.UpdateDatabaseCommand.<>c__DisplayClass2.<.ctor>b__0()
at System.Data.Entity.Migrations.MigrationsDomainCommand.Execute(Action command)
ClientConnectionId:88b66414-8776-45cd-a211-e81b2711c94b
There is already an object named 'AboutUs' in the database.
PM>
移行プロセスに問題があるようです。「Package Managerコンソール」でadd-migrationコマンドを実行します。
追加移行の初期-IgnoreChanges
いくつかの変更を行ってから、「初期」ファイルからデータベースを更新します。
更新データベース - 詳細
編集: - IgnoreChangesはEF 6に含まれていますが、EF Coreには含まれていません。 https://stackoverflow.com/a/ 43687656/495455
プロジェクトのネームスペースを変更したかもしれません。
データベースにはdbo.__MigrationHistory
というテーブルがあります。テーブルにはContextKey
という列があります。
この列の値は、namespace
に基づいています。たとえば「DataAccess.Migrations.Configuration
」です。
名前空間を変更すると、異なる名前空間を持つテーブル名が重複します。
したがって、コード側でネームスペースを変更した後は、データベース内のこのテーブルのネームスペースも変更します(すべての行に対して)。
たとえば、ネームスペースをEFDataAccess
に変更した場合は、dbo.__MigrationHistory
のContextKey
列の値を "EFDataAccess.Migrations.Configuration
"に変更する必要があります。
次にコード側では、Tools => Package Manager Consoleで、update-database
コマンドを使用します。
データベースのコンテキスト値を変更する代わりの別のオプションは、コード内のコンテキスト値を古いネームスペース値にハードコードすることです。これはDbMigrationsConfiguration<YourDbContext>
を継承し、コンストラクタでMigrateDatabaseToLatestVersion<YourDbContext, YourDbMigrationConfiguration>
から継承してそのクラスを空のままにするのではなく、古いコンテキスト値をContextKey
に割り当てるだけで可能になります。最後にやることは、静的コンストラクタのDbContextでDatabase.SetInitializer(new YourDbInitializer());
を呼び出すことです。
あなたの問題が解決することを願っています。
「データベースに「AboutUs」という名前のオブジェクトが既に存在します。」
この例外は、「AboutUs」という名前のオブジェクトがすでにデータベースに追加されていることを示しています。
この場合、データベースのバージョンはあなたによって管理されていないため、AutomaticMigrationsEnabled = true;
がそれを引き起こす可能性があります。予期しないマイグレーションを避け、チームのすべての開発者が同じデータベース構造で作業するようにするために、AutomaticMigrationsEnabled = false;
を設定することをお勧めします。
あなたが非常に注意深く、そしてプロジェクトの唯一の開発者であるならば、自動マイグレーションとコードマイグレーションは並存することができます。
Data Developer Centerに投稿されたAutomatic Code First Migrationsからの引用があります :
自動移行では、変更するたびにプロジェクト内にコードファイルがなくてもコード優先移行を使用できます。すべての変更を自動的に適用できるわけではありません。たとえば、列名の変更にはコードベースの移行を使用する必要があります。
チーム環境に対する推奨事項
自動およびコードベースの移行を点在させることができますが、これはチーム開発シナリオではお勧めできません。あなたがソース管理を使用する開発者のチームの一員であるならば、あなたは純粋に自動マイグレーションか純粋にコードベースのマイグレーションを使うべきです。自動移行には限界があるため、チーム環境ではコードベースの移行を使用することをお勧めします。
私の場合、私のEFMigrationsHistory
テーブルは空になっていて(どういうわけか)、update-database
を実行しようとすると次のようになります。
データベースに 'AspNetUsers'という名前のオブジェクトが既に存在します
テーブルが空になったのを確認した後、最初の移行を再実行し、テーブルを再作成しようとしていたことは意味がありました。
この問題を解決するために、EFMigrationsHistory
テーブルに行を追加しました。データベースが最新のものであることがわかっていることをマイグレーションごとに1行。
行には2つの列があります。MigrationId
とProductVersion
MigrationId
は、移行ファイルの名前です。例:20170628112345_Initial
ProductVersion
は実行しているefのバージョンです。これを見つけるには、パッケージマネージャコンソールにGet-Package
と入力してefパッケージを探します。
これが誰かに役立つことを願っています。
私の場合は、コードファーストエンティティフレームワークモデルを含むアセンブリの名前を変更しました。実際のスキーマは、呼び出されたすべてのmigrationsテーブルでは変更されていませんが
dbo.__MigrationHistory
oldアセンブリ名に基づいてすでに実行された移行のリストを含みます。マイグレーションテーブル内の古い名前を新しいものと一致するように更新した後、マイグレーションは再度機能しました。
ソリューション起動プロジェクトの設定ファイルに正しい接続文字列があることを確認してください。または、update-databaseコマンドを実行するときに-StartUpProjectNameパラメーターを設定してください。 -StartUpProjectNameパラメーターは、名前付き接続文字列に使用する構成ファイルを指定します。省略した場合は、指定したプロジェクトの設定ファイルが使用されます。
これはef-migrationコマンドリファレンスへのリンクです http://coding.abel.nu/2012/03/ef-migrations-command-reference/
私の場合、問題はSeederにありました。その中で_ctx.Database.EnsureCreated()を呼び出していましたが、私の知る限りではupdate databaseコマンドは正常に実行されていましたが、シーダーはデータベースを2回目に作成しようとしました。
対処方法:
私は同じ問題を抱えていました、そして3時間の苦労の後に私は何が起こっているのかを調べます
私の場合、up()
メソッドで初めて移行したいときは、デフォルトコードで既に存在しているテーブルを作成したいので、同じエラーが発生します。
それを解決するには、それらのコードを削除して欲しいと書いてください。たとえば、私はちょうど書くように私は列を追加したいと思いました
migrationBuilder.AddColumn<string>(
name: "fieldName",
table: "tableName",
nullable: true);
注:推奨される解決策はありません。しかしいくつかのケースでは迅速な修正。
私にとって、本番データベースのdbo._MigrationHistory
は、公開プロセス中に移行レコードを見逃していましたが、開発データベースにはすべての移行レコードがありました。
Production dbがdev dbと比較して最新で同じスキーマを持っていることが確実な場合は、すべての移行レコードをproduction dbにコピーすることで問題を解決できます。
あなたはVisualStudioだけですることができます。
dbo._MigrationHistory
テーブルを右クリックし、[データ比較...]メニューをクリックします。繰り返しますが、複雑で深刻なプロジェクトではお勧めできません。これは、ASP.NetまたはEntityFrameworkの学習中に問題がある場合にのみ使用してください。
Dbo_MigrationHistoryテーブルから行を削除するか、テーブルを削除して実行します。
update-database -verbose
プロジェクト内のすべての移行が1つずつ実行されます。
何時間も結果を得られなかった1時間以上経った後、私は移行を使用せずに別のアプローチを試みましたが、私はスキーマ比較をしました。
Visual Studioの場合 - >ツール - > SQL Server - >新しいスキーマ比較
最初に、EFの移行を使用して、まったく新しいデータベースを新しく作成しました。私が比較したのは、新しいデータベースと私が更新したいデータベースを比較したときです。最後に移行スクリプトを生成したので、スキーマの更新を実行できました。
私の場合(リセットして新しいデータベースを取得したい)、
最初に私はエラーメッセージを得ました:There is already an object named 'TABLENAME' in the database.
少し前に見ました。
"Applying migration '20111111111111_InitialCreate'.
Failed executing DbCommand (16ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE MYFIRSTTABLENAME"
私のデータベースは作成されましたが、移行履歴の記録はありません。
Dbo以外のすべてのテーブルを削除します。__MigrationsHistory
MigrationsHistoryが空でした。
dotnet ef database update -c StudyContext --verbose
を実行する
( - 楽しみのためだけに冗長)
そしてDone.
を得ました
別のエッジケースEFコアシナリオ.
Migrations/YOURNAMEContextModelSnapshot.csファイルがあることを確認してください。
- https://docs.Microsoft.com/ja-jp/ef/core/managing-schemas/migrations/#create-a-migration に詳述されているように
Migration.csファイルを削除してデータベースを手動で再作成しようとした場合は、Migrations/* ContextModelSnapshot.csファイルがまだ存在することに注意してください。
それがなければ、それ以降のマイグレーションには必要な違いを作成するためのスナップショットがなく、新しいマイグレーションファイルは最初からすべてを再作成しているように見えるので、上記のように既存のテーブルエラーが発生します。
単にupdate-migration -Scriptコマンドを実行してください。これにより、移行に含まれるすべてのDBの変更を含む新しい* .sqlスクリプトが生成されます。コードの最後に次のような挿入コマンドがあります。INSERT [dbo]。[__ MigrationHistory]([MigrationId]、[ContextKey]、[Model]、[ProductVersion])あなたはこれを単に実行することができますINSERTとDBは同期されます