在数据库中已经存在一个被命名的对象。

144

从程序包管理器控制台更新数据库失败。

我使用了Entity Framework 6.x和Code First方法。

错误信息为"There is already an object named 'AboutUs' in the database."

我该如何解决这个问题?

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> 

我该怎么做(映射到现有设计)? - x19
15
如果“精心设计的数据库”可以使用EF映射到对象模型中,那么EF也可以生成它。数据库迁移是一种强大的工具,可以使您的数据库部署更加容易。我不建议避免使用数据库迁移。否则,补丁脚本仍然是必需的。我建议正确使用数据库迁移。 - Ilya Palkin
31个回答

0
经过一个多小时没有得到任何结果后,我尝试了另一种方法,不使用迁移而是进行模式比较。
在Visual Studio中->工具->SQL Server->新建模式比较
首先,我使用EF迁移创建了一个全新的数据库。然后,我进行了比较,将新数据库与我想要更新的数据库进行比较。最后生成了一个迁移脚本,我就可以执行模式更新了。

0

我遇到了与下面一样的错误,然后我按以下步骤修复了它:

  1. 检查项目中当前的数据库:
    • dotnet ef migrations list
  2. 如果最新的是你添加的,则删除它:
    • dotnet ef migrations remove
  3. 确保在源代码中删除该数据库的输出:.cs/.Designer.cs文件

4.现在没问题了。尝试重新添加: dotnet ef migrations add [new_dbo_name]

5.最后,根据迁移列表进行更新:

  • dotnet ef database update [First]
  • dotnet ef database update [Second]
  • ...
  • dotnet ef database update [new_dbo_name]

希望对您有所帮助。^^


0
当你运行 update-database 命令时,它将检查数据库中的 __EFMigrationsHistory 表记录和项目中的 EfMigration 文件夹中的条目,如果您在项目文件夹中有一个迁移项,而该迁移项不存在于数据库 ef core 中,则开始在数据库中应用这些迁移,最终您可能会遇到此类错误。因此,请将 EfMigration 文件夹中的项目与数据库中的 __EFMigrationsHistory 表进行比较,并确保它们同步并且相同。如果您的项目中有任何未在数据库中的条目,请将其记录添加到数据库中以保持两者同步。(实际上,这可能是由于您可能在 db 中截断了__EFMigrationHistory 表而导致的。)

0

遇到了类似的问题,发现使用的连接来自发布配置文件,即使我已经在appsettings.json中更改了连接。这导致迁移尝试创建一个已经存在的表。在项目的Connected Services中修改连接解决了我的问题。


0

只需执行update-migration -Script命令即可。这将生成一个新的*.sql脚本,其中包含迁移中包含的所有数据库更改。在代码的末尾是类似于以下内容的插入命令:INSERT [dbo].[__MigrationHistory]([MigrationId], [ContextKey], [Model], [ProductVersion]),您可以简单地运行所有这些INSERT,然后数据库将同步。


0
我在想要向现有数据库添加新表时遇到了同样的问题。 我的情况是:首先,我通过第一种代码方法创建了一个名为DBShop的数据库,并在其中创建了一个表(T_User)。然后,在我更改了模型并添加了两个模型(Production和Shop)之后,为了在这两个新模型中创建表格,我收到了一个错误,即数据库中存在一个名为T_User的表格。 为了解决这个问题,在运行Add-migration CreateDB -force之后,在更新数据库之前,我参考了移民文件夹中的CreateDB.cs文件,并删除了与T_User表相关的CreateTable方法,然后运行update-database -verbose。

这是第30个答案。它真的有什么新的东西吗?即使有,描述也非常不清楚为什么首先会出现错误。 - Gert Arnold

0
在数据库中,查询 __MigrationHistory 表并复制 [ContextKey]。
将其粘贴到 DbMigrationsConfiguration ConextKey 中,如下所示。
internal sealed class DbConfiguration: DbMigrationsConfiguration<DbContext>
    {
        public DbConfiguration()
        {
            AutomaticMigrationsEnabled = true;
            ContextKey = "<contextKey from above>";
        }

-1
以下步骤对我解决了同样的问题:
情景: 我试图为我的现有模型添加两个新字段以实现电子邮件功能。这两个新字段是“IsEmailVerified”和“ActivationCode”。
我采取的步骤如下:
1. 删除“迁移”文件夹下的旧迁移文件,以允许我执行Update-Database操作。 2. 撤销我在模型上最近进行的所有更改。
3. 运行以下命令: Add-Migration -ConnectionProviderName System.Data.SqlClient -ConnectionString "Data Source=DESKTOP\SQLEXPRESS;Initial Catalog=Custom;Persist Security Info=True;User ID=sa;password=****"
4. 从迁移文件中删除Up()和Down()方法的内容,并将这些方法保留为空。
5. 运行以下命令: Update-Database -ConnectionProviderName System.Data.SqlClient -ConnectionString "Data Source=DESKTOP\SQLEXPRESS;Initial Catalog=Custom;Persist Security Info=True;User ID=sa;password=***"
执行完上述步骤后,模型和数据库看起来同步了。 现在,我在模型中添加了新属性: public bool IsEmailVerified { get; set; } public Guid ActivationCode { get; set; } 运行以下命令:

Add-Migration -ConnectionProviderName System.Data.SqlClient -ConnectionString "Data Source=DESKTOP\SQLEXPRESS;Initial Catalog=Custom;Persist Security Info=True;User ID=sa;password="***

添加迁移-连接提供程序名称System.Data.SqlClient-连接字符串"Data Source=DESKTOP\SQLEXPRESS;Initial Catalog=Custom;PersistSecurityInfo=True;User ID=sa;password="***

  • 现在迁移文件仅包含以下最近的更改:

       public override void Up()
         {
             AddColumn("dbo.UserAccounts", "IsEmailVerified", c => c.Boolean(nullable: false));
             AddColumn("dbo.UserAccounts", "ActivationCode", c => c.Guid(nullable: false));
         }        
         public override void Down()
         {
             DropColumn("dbo.UserAccounts", "ActivationCode");
             DropColumn("dbo.UserAccounts", "IsEmailVerified");
         }
    
  • 运行以下命令: Update-Database -ConnectionProviderName System.Data.SqlClient -ConnectionString "Data Source=DESKTOP\SQLEXPRESS;Initial Catalog=Custom;Persist Security Info=True;User ID=sa;password="***

  • 11.现在我已经成功地使用附加列更新了数据库。

    以下是最近更改后的更新表:

    更新迁移后的表


    真的不建议这样做,删除生产迁移将会破坏您的环境。如果迄今为止它们都正常工作,为什么要删除您的迁移呢?并且您的连接字符串不适用于每个用户,不应该像那样运行它们。 - rakuens

    -1

    也许您已经更改了命名空间 Configuration.cs。 您的数据库中有一个名为 dbo.__MigrationHistory 的表。该表有一个名为 ContextKey 的列。

    new namespace  AppData.Migrations { internal sealed class Configuration }
    sql command
     update   [__MigrationHistory] set [ContextKey]= 'AppData.Migrations.Configuration'
    

    至少有两个现有的答案建议这样做。在发布新答案之前,请先查看其他答案。 - Gert Arnold

    -1

    您也可以前往编辑上一次迁移的文件("201410101740197_AutomaticMigration.cs"),并清空Up()Down()函数内的代码。

    public override void Up()
    {
    }
    public override void Down()
    {
    }
    

    如果您的数据库模型(AboutUs模型)代码与数据库表(更多字段...)不同,则可能会出现一些问题,那么您应该从模型代码中删除它,或者您可以手动更新移民文件中的Up/Down函数但保持差异。

    public override void Up()
    {  
      // Keep difference from model with DB table here
    }        
    public override void Down()
    {   
      // Keep difference from model with DB table here        
    }
    

    请注意文本格式。 - Gert Arnold

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接