数据库中已经有一个对象

时间:2014-10-10 17:53:15

标签: database entity-framework ef-code-first entity-framework-6 ef-migrations

更新 - 数据库管理器控制台失败。 我使用了Entity Framework 6.x和代码优先方法。 错误是

"已经有一个名为'关于我们的对象'在数据库中。"

我该如何解决这个问题?

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> 

26 个答案:

答案 0 :(得分:116)

似乎迁移过程中存在问题,在“程序包管理器控制台”中运行add-migration命令:

  

Add-Migration Initial -IgnoreChanges

进行一些更改,然后从“Initial”文件更新数据库:

  

更新 - 数据库-verbose

修改 -IgnoreChanges在EF6中但不在EF Core中,这是一个解决方法: https://stackoverflow.com/a/43687656/495455

答案 1 :(得分:64)

也许您已经更改了项目中的命名空间!
您的数据库中有一个名为 dbo.__MigrationHistory 的表格。该表格中有一个名为 ContextKey 的列 此列的值基于 namespace 。例如是“DataAccess.Migrations.Configuration更改命名空间时,会导致具有不同命名空间的重复表名称。
因此,在代码端更改名称空间后,也要在数据库中更改此表中的名称空间(对于所有行) 例如,如果您将命名空间更改为EFDataAccess,则应将ContextKeydbo.__MigrationHistory列的值更改为“EFDataAccess.Migrations.Configuration”。 然后在代码方面,在Tools =&gt;软件包管理器控制台,使用 update-database 命令。

另一个选项是将代码中的上下文值硬编码为旧的命名空间值,而不是更改数据库中的上下文值。这可以通过继承DbMigrationsConfiguration<YourDbContext>来实现,并在构造函数中将旧的上下文值分配给ContextKey,而不是从MigrateDatabaseToLatestVersion<YourDbContext, YourDbMigrationConfiguration>继承并将该类留空。最后要做的是在静态构造函数中调用DbContext中的Database.SetInitializer(new YourDbInitializer());

我希望你的问题能得到解决。

答案 2 :(得分:16)

  

&#34;已经有一个名为&#39; AboutUs&#39;在数据库中。&#34;

此异常告诉您有人添加了一个名为&#39; AboutUs&#39;已经到了数据库。

AutomaticMigrationsEnabled = true;可以导致它,因为在这种情况下数据库版本不受您控制。为了避免不可预测的迁移,并确保团队中的每个开发人员都使用相同的数据库结构我建议您设置AutomaticMigrationsEnabled = false;

如果您非常小心并且是项目中唯一的开发人员,则自动迁移和编码迁移可以同时存在。

There is a quote from Automatic Code First Migrations post on Data Developer Center

  

自动迁移允许您在不使用代码优先迁移的情况下使用   在您的项目中为您所做的每项更改都有一个代码文件。不是全部   可以自动应用更改 - 例如列重命名   需要使用基于代码的迁移。

     

团队环境建议

     

您可以散布自动和基于代码的迁移,但这是   不建议在团队开发方案中使用。如果你是一个人的一部分   使用源代码控制的开发人员团队应该使用   纯粹的自动迁移或纯粹基于代码的迁移。鉴于   我们建议使用基于代码的自动迁移限制   团队环境中的迁移。

答案 3 :(得分:7)

在我的情况下,我的EFMigrationsHistory表被清空(不知何故),当我试图运行update-database时,我会得到:

  

数据库中已有一个名为'AspNetUsers'的对象

看到桌子被清空后,有意义的是它试图重新运行初始迁移并尝试重新创建表格。

要解决此问题,我在EFMigrationsHistory表中添加了行。我知道数据库是最新的每次迁移都有1行。

一行有两列:MigrationIdProductVersion

MigrationId是您的迁移文件的名称。示例:20170628112345_Initial

ProductVersion是您正在运行的ef版本。您可以通过在程序包管理器控制台中键入Get-Package并查找您的ef包来找到它。

希望这对某人有帮助。

答案 4 :(得分:6)

在我的例子中,我重新命名了包含代码优先实体框架模型的程序集。虽然实际模式在所有名为

的迁移表中都没有更改
dbo.__MigrationHistory

包含基于程序集名称的已执行迁移的列表。我更新了迁移表中的旧名称以匹配新名称,然后迁移再次运行。

答案 5 :(得分:5)

确保您的解决方案启动项目在配置文件中具有正确的连接字符串。或者在执行update-database命令时设置-StartUpProjectName参数。 -StartUpProjectName参数指定用于命名连接字符串的配置文件。如果省略,则使用指定项目的配置文件。

以下是ef-migration命令参考的链接 http://coding.abel.nu/2012/03/ef-migrations-command-reference/

答案 6 :(得分:1)

从dbo_MigrationHistory表中删除行或删除表并运行

update-database -verbose

它将逐个运行项目中的所有迁移

答案 7 :(得分:1)

注意:不建议使用解决方案。但在某些情况下可以快速解决。

对我来说,生产数据库中的dbo._MigrationHistory在发布过程中错过了迁移记录,但是开发数据库有所有迁移记录。

如果您确定生产数据库与dev db相比具有相同和最新的模式,则将所有迁移记录复制到生产数据库可以解决问题。

您可以单独使用VisualStudio。

  1. 打开&#39; SQL Server对象资源管理器&#39;面板&gt;右键单击源中的dbo._MigrationHistory表(在我的案例中为dev db)数据库&gt;点击&#34;数据比较...&#34;菜单。
  2. 然后,数据比较向导启动,选择目标数据库(在我的案例中为生产数据库),然后单击“下一步”。
  3. 几秒钟后,它只会在源数据库中显示一些记录。只需点击“更新目标”即可。按钮。
  4. 在浏览器中,点击刷新按钮,看到错误消息消失。
  5. 请注意,同样,不建议在复杂而严肃的项目中使用。只有在ASP.Net或EntityFramework学习期间才有问题。

答案 8 :(得分:1)

就我而言,问题出在Seeder。我在其中调用了_ctx.Database.EnsureCreated(),据我所知,更新数据库命令已成功执行,但是然后播种器尝试创建数据库&#34; second&#34;时间。

如何解决:

  1. 坚果运行更新,只需启动应用程序并调用EnsureCreated()。将创建/更新数据库
  2. 注释掉或删除播种机。

答案 9 :(得分:1)

相同情况(服务器上没有DB和MigrationHistory表)。我的步骤:

  1. 我从第一次迁移的“向上”和“向下”部分删除了迁移数据。
  2. 使用空迁移更新数据库(已创建MigrationHistory表)
  3. 添加您的REAL迁移并使用它来更新数据库。

答案 10 :(得分:1)

我遇到了同样的问题,经过三个小时的奋斗,我发现发生了什么事

在我的情况下,当我想首次使用up()方法进行迁移时,默认代码希望创建已经存在的表,所以我和您遇到了相同的错误

要解决此问题,只需删除这些代码并编写所需的代码即可。例如,我想添加一列,所以我只写

migrationBuilder.AddColumn<string>(
            name: "fieldName",
            table: "tableName",
            nullable: true);

答案 11 :(得分:1)

我遇到了与Elnaz给出的答案相同的问题。我需要在重构项目期间更改数据层的名称空间。这导致迁移看不到数据库中的现有迁移。我找到了詹姆斯·钱伯斯(James Chambers)博客写的一个很好的答案。

http://jameschambers.com/2014/02/changing-the-namespace-with-entity-framework-6-0-code-first-databases/

我只是在“迁移”配置文件中更改了以下内容。

public Configuration()
{
    AutomaticMigrationsEnabled = false;
    this.ContextKey = “Old_Namespace.Migrations.Configuration”;
}

希望这可以帮助绑定中的其他人。

答案 12 :(得分:0)

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

答案 13 :(得分:0)

在数据库中,查询__MigrationHistory表并复制[ContextKey]。

按如下所示将其粘贴到DbMigrationsConfiguration ConextKey中

internal sealed class DbConfiguration: DbMigrationsConfiguration<DbContext>
    {
        public DbConfiguration()
        {
            AutomaticMigrationsEnabled = true;
            ContextKey = "<contextKey from above>";
        }

答案 14 :(得分:0)

注意:之所以这样做,是因为我的数据库中没有任何内容。 就我而言: 1.我通过 Package Manager控制台中的命令 remove-migration 删除了迁移 2.通过“ SQL Server对象资源管理器”面板>在当前数据库上>右键单击>删除来删除数据库 3.在 Package Manager控制台中迁移后,写入 Add-Migration ,然后单击Enter 4.最近通过命令 update-database

进行的更新

答案 15 :(得分:0)

我面临着同样的问题。我尝试以下解决方案: 1.从Up()中删除创建表代码,并从Down()方法中删除相关代码 2.在Package Manager Consol中运行update-database命令

这解决了我的问题

答案 16 :(得分:0)

另一种方法是在Up和Down方法之间注释Initial Class中的所有内容。然后在运行种子方法成功后运行update-database,因此再次运行update-database。这可能对某些朋友有所帮助。

答案 17 :(得分:0)

您已删除迁移文件夹,而不是要在程序包管理器控制台上运行“ update-database”命令的目录?如果是这样

只需手动删除所有表 比运行update-databse(将删除种子数据)更容易

答案 18 :(得分:0)

我也发生了同样的事情。 问题是实际上我删除了数据库表MoviesCast并创建了新表,问题是我的上一次迁移正试图在数据库中引入已删除的表MoviesCast。 我通过简单地删除上一次迁移的所有内容并仅运行Up()和down()方法来解决了该问题

public override void Up()
{
}

public override void Down()
{
}

然后更新数据库,只需添加新的迁移

答案 19 :(得分: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]

希望对您有帮助。 ^^

答案 20 :(得分:0)

就我而言(想重置并获取新的数据库),

首先,我得到了错误消息: 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.

答案 21 :(得分:0)

另一种极端情况下的EF核心方案。

检查您是否具有 Migrations / YOURNAMEContextModelSnapshot.cs 文件。

详细信息-https://docs.microsoft.com/en-us/ef/core/managing-schemas/migrations/#create-a-migration

如果您尝试通过删除migration.cs文件手动重新创建数据库,请注意您的Migrations / * ContextModelSnapshot.cs文件仍然存在。

没有它,您的后续迁移将没有快照来创建所需的差异,并且新的迁移文件看起来就像是它们从头开始重新创建所有内容一样,然后您将得到如上所述的现有表错误。

答案 22 :(得分:0)

一个多小时没有得到任何结果之后,我尝试了另一种方法,不使用迁移,但是进行了模式比较。

在Visual Studio中->工具-> SQL Server->新架构比较

首先,我使用EF迁移创建了一个全新的数据库。比我进行了比较,将新数据库与我要更新的数据库进行了比较。最终生成了一个迁移脚本,我可以执行模式更新。

答案 23 :(得分:0)

只需执行命令update-migration -Script即可。这将生成新的* .sql脚本,其中包括迁移中包含的所有数据库更改。在代码的末尾是insert命令,如下所示:INSERT [dbo]。[__ MigrationHistory]([MigrationId],[ContextKey],[Model],[ProductVersion])你可以简单地运行这个INSERT和DB将被同步< / p>

答案 24 :(得分:-1)

以下步骤对我来说适用于同一问题:

场景:

我试图在现有模型中为电子邮件功能添加2个新字段。新字段是“ IsEmailVerified”和“ ActivationCode”

我遵循的步骤:

1。删除“ Migrations”文件夹下的旧迁移文件,这些文件使我无法执行Update-Database 2.还原了我最近在模型上所做的所有更改

3。运行以下命令:

添加迁移-ConnectionProviderName System.Data.SqlClient -ConnectionString“数据源= DESKTOP \ SQLEXPRESS;初始目录=自定义;持久安全信息= True;用户ID = sa;密码= ****

4。从迁移文件中删除Up()和Down()方法的内容,并将这些方法留空

5。运行以下命令:

更新数据库-ConnectionProviderName System.Data.SqlClient -ConnectionString“数据源= DESKTOP \ SQLEXPRESS;初始目录=自定义;持久安全信息=真实;用户ID = sa;密码= “ ***

  1. 执行完上述步骤后,模型和数据库看起来已同步。

  2. 现在,我在模型中添加了新属性

         public bool IsEmailVerified { get; set; }
         public Guid ActivationCode { get; set; }
    
  3. 运行以下命令:

添加迁移-ConnectionProviderName System.Data.SqlClient -ConnectionString“数据源= DESKTOP \ SQLEXPRESS;初始目录=自定义;持久安全信息= True;用户ID = sa;密码= “ ***

  1. 现在,迁移文件仅包含我最近的更改,如下所示:

       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");
         }
    
  2. 运行以下命令: 更新数据库-ConnectionProviderName System.Data.SqlClient -ConnectionString“数据源= DESKTOP \ SQLEXPRESS;初始目录=自定义;持久安全信息=真实;用户ID = sa;密码= “ ***

11。现在,我成功地用其他列更新了数据库。

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

Table after the update migration

答案 25 :(得分:-4)

在迁移文件中,检查公共覆盖void Up()方法。可能是您正在尝试创建已在数据库中的新数据库对象。 因此,您需要在创建db对象之前删除此对象/表。就像吼叫一样 -

DropTable("dbo.ABC"); 
CreateTable(
            "dbo.ABC",
            c => new
                {
                    Id = c.Int(nullable: false, identity: true),
                    ..
                 }

现在运行您的迁移       Update-Database -TargetMigration: "2016_YourMigration"