数据库中已经有一个对象

Jah*_*han 100 database entity-framework ef-code-first ef-migrations entity-framework-6

程序包管理器控制台中的Update-Database失败.我使用了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)
    {

    }
}
Run Code Online (Sandbox Code Playgroud)

我的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; }
}
Run Code Online (Sandbox Code Playgroud)

包管理控制台:

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> 
Run Code Online (Sandbox Code Playgroud)

Sin*_*ari 120

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

Add-Migration Initial -IgnoreChanges

做一些更改,然后从"初始"文件更新数据库:

Update-Database -verbose

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

  • 这究竟是做什么的?这是否允许新模型覆盖旧模型? (7认同)
  • 添加迁移:找不到与参数名称"IgnoreChanges"匹配的参数. (5认同)
  • 这只会让我陷入无限循环:Package Manager Console不允许我进行Add-Migration,因为它会出现错误"无法生成显式迁移,因为以下显式迁移正在等待......"即InitialCreate.但是如果我无法成功运行Update-Database UNTIL,那么还有一些初始的-IgnoreChanges,那么我该怎么做? (3认同)
  • 对于迁移表,@ TravisTubbs会忽略您所做的更改以及模型与db同步的"假货".你仍然需要手动同步这两个; 在我的情况下,我删除了对模型所做的更改,执行了Add-Migration,在执行update-database之前从up/down方法中删除了内容 - 这使我返回到迁移之前的状态.然后我实际上像往常一样重新添加了更改,添加迁移和更新数据库 - 这次一切都已同步 (2认同)

Eln*_*naz 68

也许您已经更改了项目中的命名空间!
您的数据库中有一个名为的表dbo.__MigrationHistory.该表有一个名为的列ContextKey.
此列的值基于您的namespace.例如是" DataAccess.Migrations.Configuration".
更改命名空间时,会导致具有不同命名空间的重复表名称.
因此,在代码端更改命名空间后,也要在数据库中更改此表中的命名空间(对于所有行).
例如,如果将名称空间更改为EFDataAccess,则应将ContextKey列的值更改dbo.__MigrationHistory为" EFDataAccess.Migrations.Configuration".
然后在代码端,在Tools => Package Manager Console中,使用该update-database命令.

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

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

  • 太棒了,我们确实有这个问题! (8认同)
  • 实际上,这是此错误的真正原因。EF尝试创建数据库,因为由于名称空间差异,它无法读取应用于数据库的哪些迁移 (2认同)

Ily*_*kin 17

"数据库中已经有一个名为'AboutUs'的对象."

此异常告诉您有人已经将名为"AboutUs"的对象添加到数据库中.

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

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

Data Developer Center上的自动代码优先迁移帖子引用了一句话:

自动迁移允许您使用代码优先迁移,而无需在项目中为每个更改生成代码文件.并非所有更改都可以自动应用 - 例如,列重命名需要使用基于代码的迁移.

团队环境建议

您可以散布自动和基于代码的迁移,但在团队开发方案中不建议这样做.如果您是使用源代码管理的开发人员团队的一员,则应使用纯自动迁移或纯粹基于代码的迁移.鉴于自动迁移的局限性,我们建议在团队环境中使用基于代码的迁移.


Kol*_*lby 8

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

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

在看到表已经清空后,有意义的是它试图重新运行初始迁移并尝试重新创建表.

为了解决这个问题,我在EFMigrationsHistory表格中添加了行.我知道数据库是最新的每次迁移都有1行.

一行将有2列:MigrationIdProductVersion

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

ProductVersion是你正在运行的ef版本.您可以通过Get-Package在Package Manager控制台中输入并查找您的ef包来找到它.

希望这对某人有帮助.


The*_*tor 6

在我的例子中,我重新命名了包含代码优先实体框架模型的程序集.虽然实际模式在所有迁移表中都没有更改

dbo.__MigrationHistory
Run Code Online (Sandbox Code Playgroud)

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


Rya*_*ton 5

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

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


小智 5

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

就我而言,当我第一次想迁移时,在up()方法中,默认代码想要创建已经存在的表,所以我得到了与您相同的错误

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

migrationBuilder.AddColumn<string>(
            name: "fieldName",
            table: "tableName",
            nullable: true);
Run Code Online (Sandbox Code Playgroud)

  • 添加代码片段@arfa 做得很好。不需要按摩:)。如果您想给我发消息,只需在评论部分输入“@”,然后输入我的用户名。 (3认同)