database 数据库中已经有一个命名的对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26305273/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
There is already an object named in the database
提问by Said Roohullah Allem
Update-Database failed from Package Manager Console. I've used Entity Framework 6.x and code-first approach. Error is
从包管理器控制台更新数据库失败。我使用了实体框架 6.x 和代码优先的方法。错误是
"There is already an object named 'AboutUs' in the database."
“数据库中已经有一个名为‘AboutUs’的对象。”
How can I solve this problem?
我怎么解决这个问题?
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)
{
}
}
My DbContext is:
我的 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; }
}
Package Manage Console:
包管理控制台:
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>
回答by Sina Amirshekari
it seems there is a problem in migration process, run add-migration command in "Package Manager Console":
迁移过程中似乎存在问题,在“包管理器控制台”中运行 add-migration 命令:
Add-Migration Initial -IgnoreChanges
添加迁移初始 -IgnoreChanges
do some changes, and then update database from "Initial" file:
做一些更改,然后从“初始”文件更新数据库:
Update-Database -verbose
更新数据库 -verbose
Edit:-IgnoreChanges is in EF6 but not in EF Core, here's a workaround: https://stackoverflow.com/a/43687656/495455
编辑:-IgnoreChanges 在 EF6 中但不在 EF Core 中,这是一种解决方法:https ://stackoverflow.com/a/43687656/495455
回答by Elnaz
Maybe you have changed the namespace in your project!
There is a table in your data base called dbo.__MigrationHistory
. The table has a column called ContextKey
.
The value of this column is based on your namespace
. for example is "DataAccess.Migrations.Configuration
".
When you change the namespace, it causes duplicate table names with different namespaces.
So, after you change namespace in code side, change the namespace in this table in database, too, (for all rows).
For example, if you change the namespace to EFDataAccess
, then you should change the values of ContextKey
column in dbo.__MigrationHistory
to "EFDataAccess.Migrations.Configuration
".
Then in code side, in Tools => Package Manager Console, use the update-database
command.
也许您已经更改了项目中的命名空间!
您的数据库中有一个名为dbo.__MigrationHistory
. 该表有一个名为 的列ContextKey
。
此列的值基于您的namespace
. 例如是“ DataAccess.Migrations.Configuration
”。
当您更改命名空间时,会导致具有不同命名空间的重复表名。
因此,在代码端更改命名空间后,也要更改数据库中此表中的命名空间(对于所有行)。
例如,如果您将命名空间更改为EFDataAccess
,那么您应该将ContextKey
列的值更改dbo.__MigrationHistory
为“ EFDataAccess.Migrations.Configuration
”。
然后在代码端,在工具 => 包管理器控制台中,使用update-database
命令。
Another option instead of changing the context value in the database is to hard code the context value in your code to the old namespace value. This is possible by inheriting DbMigrationsConfiguration<YourDbContext>
and in the constructor just assign the old context value to ContextKey
, than inherit from MigrateDatabaseToLatestVersion<YourDbContext, YourDbMigrationConfiguration>
and leave that class empty. The last thing to do is call Database.SetInitializer(new YourDbInitializer());
in your DbContext in a static constructor.
另一种不更改数据库中的上下文值的选择是将代码中的上下文值硬编码为旧的命名空间值。这可以通过继承DbMigrationsConfiguration<YourDbContext>
和在构造函数中将旧的上下文值分配给ContextKey
,而不是从MigrateDatabaseToLatestVersion<YourDbContext, YourDbMigrationConfiguration>
该类继承并将其留空。最后要做的是Database.SetInitializer(new YourDbInitializer());
在静态构造函数中调用DbContext。
I hope your problem will be fixed.
我希望你的问题会得到解决。
回答by Ilya Palkin
"There is already an object named 'AboutUs' in the database."
“数据库中已经有一个名为‘AboutUs’的对象。”
This exception tells you that somebody has added an object named 'AboutUs' to the database already.
此异常告诉您有人已将名为“AboutUs”的对象添加到数据库中。
AutomaticMigrationsEnabled = true;
can lead to it since data base versions are not controlled by you in this case. In order to avoid unpredictable migrations and make sure that every developer on the team works with the same data base structure I suggest you set AutomaticMigrationsEnabled = false;
.
AutomaticMigrationsEnabled = true;
可能会导致它,因为在这种情况下数据库版本不受您控制。为了避免不可预测的迁移并确保团队中的每个开发人员都使用相同的数据库结构,我建议您设置AutomaticMigrationsEnabled = false;
.
Automatic migrations and Coded migrations can live alongside if you are very careful and the only one developer on a project.
如果您非常小心并且是项目中唯一的开发人员,那么自动迁移和编码迁移可以同时存在。
There is a quote from Automatic Code First Migrations post on Data Developer Center:
Automatic Migrations allows you to use Code First Migrations without having a code file in your project for each change you make. Not all changes can be applied automatically - for example column renames require the use of a code-based migration.
Recommendation for Team Environments
You can intersperse automatic and code-based migrations but this is not recommended in team development scenarios. If you are part of a team of developers that use source control you should either use purely automatic migrations or purely code-based migrations. Given the limitations of automatic migrations we recommend using code-based migrations in team environments.
自动迁移允许您使用 Code First 迁移,而无需在您的项目中为您所做的每次更改提供代码文件。并非所有更改都可以自动应用 - 例如,列重命名需要使用基于代码的迁移。
对团队环境的建议
您可以穿插自动和基于代码的迁移,但在团队开发方案中不建议这样做。如果您是使用源代码控制的开发人员团队的一员,您应该使用纯自动迁移或纯基于代码的迁移。鉴于自动迁移的局限性,我们建议在团队环境中使用基于代码的迁移。
回答by Kolby
In my case, my EFMigrationsHistory
table was emptied (somehow) and when trying to run update-database
I would get:
就我而言,我的EFMigrationsHistory
桌子被清空了(不知何故),当update-database
我尝试运行时,我会得到:
There is already an object named 'AspNetUsers' in the database
数据库中已经有一个名为“AspNetUsers”的对象
After seeing the table had been emptied it made sense that it was trying to rerun the initial migration and trying to recreate the tables.
在看到表已被清空后,它正在尝试重新运行初始迁移并尝试重新创建表是有道理的。
To fix this problem I added rows into my EFMigrationsHistory
table. 1 row for each migration that I knew the database was up to date with.
为了解决这个问题,我在EFMigrationsHistory
表中添加了行。我知道数据库是最新的每个迁移的 1 行。
A row will have 2 columns: MigrationId
and ProductVersion
一行将有 2 列:MigrationId
和ProductVersion
MigrationId
is the name of your migration file. Example: 20170628112345_Initial
MigrationId
是您的迁移文件的名称。例子:20170628112345_Initial
ProductVersion
is the ef version you're running. You can find this by typing Get-Package
into the Package Manager Console and looking for your ef package.
ProductVersion
是您正在运行的 ef 版本。您可以通过Get-Package
在包管理器控制台中键入并查找您的 ef 包来找到它。
Hope this is helpful for someone.
希望这对某人有帮助。
回答by The Senator
In my case I had re-named the assembly that contained the code-first entity framework model. Although the actual schema hadn't changed at all the migrations table called
就我而言,我重命名了包含代码优先实体框架模型的程序集。尽管实际的架构并没有改变所有名为的迁移表
dbo.__MigrationHistory
contains a list of already performed migrations based on the oldassembly name. I updated the old name in the migrations table to match the new and the migration then worked again.
包含基于旧程序集名称的已执行迁移列表。我更新了迁移表中的旧名称以匹配新名称,然后迁移再次运行。
回答by Ryan Layton
Make sure your solutions startup project has the correct connectionstring in the config file. Or set the -StartUpProjectName parameter when executing the update-database command. The -StartUpProjectName parameter specifies the configuration file to use for named connection strings. If omitted, the specified project's configuration file is used.
确保您的解决方案启动项目在配置文件中具有正确的连接字符串。或者在执行update-database 命令时设置-StartUpProjectName 参数。-StartUpProjectName 参数指定用于命名连接字符串的配置文件。如果省略,则使用指定项目的配置文件。
Here is a link for ef-migration command references http://coding.abel.nu/2012/03/ef-migrations-command-reference/
这是 ef-migration 命令参考的链接 http://coding.abel.nu/2012/03/ef-migrations-command-reference/
回答by Youngjae
Note: not recommended solution. but quick fix in some cases.
注意:不推荐的解决方案。但在某些情况下可以快速修复。
For me, dbo._MigrationHistory
in production database missed migration records during publish process, but development database had all migration records.
对我来说,dbo._MigrationHistory
生产数据库在发布过程中丢失了迁移记录,但开发数据库有所有迁移记录。
If you are sure that production db has same-and-newest schema compared to dev db, copying all migration records to production db could resolve the issue.
如果您确定生产数据库与开发数据库具有相同和最新的架构,则将所有迁移记录复制到生产数据库可以解决该问题。
You can do with VisualStudio solely.
您可以单独使用 VisualStudio。
- Open 'SQL Server Object Explorer' panel > right-click
dbo._MigrationHistory
table in source(in my case dev db) database > Click "Data Comparison..." menu. - Then, Data Comparison wizard poped up, select target database(in my case production db) and click Next.
- A few seconds later, it will show some records only in source database. just click 'Update Target' button.
- In browser, hit refresh button and see the error message gone.
- 打开“SQL Server 对象资源管理器”面板 > 右键单击
dbo._MigrationHistory
源(在我的情况下为 dev db)数据库中的表 > 单击“数据比较...”菜单。 - 然后,弹出数据比较向导,选择目标数据库(在我的例子中是生产数据库)并单击下一步。
- 几秒钟后,它将只显示源数据库中的一些记录。只需单击“更新目标”按钮。
- 在浏览器中,点击刷新按钮并查看错误消息消失。
Note that, again, it is not recommended in complex and serious project. Use this only you have problem during ASP.Net or EntityFramework learning.
请注意,同样,不建议在复杂和严肃的项目中使用。只有在 ASP.Net 或 EntityFramework 学习过程中遇到问题时才使用它。
回答by arfa
I had same problem and after three hour struggling I find out what's going on
我遇到了同样的问题,经过三个小时的努力,我发现了发生了什么
In my case, when I wanted to migrate for the first time in up()
method, the default code wants to create the tables that already existed so I got same error as you
就我而言,当我想在up()
方法中第一次迁移时,默认代码想要创建已经存在的表,所以我遇到了和你一样的错误
To solve it, just delete those code and write want you want. For example, I wanted to add a column so i just write
要解决它,只需删除那些代码并编写您想要的。例如,我想添加一列,所以我只写
migrationBuilder.AddColumn<string>(
name: "fieldName",
table: "tableName",
nullable: true);
回答by WickedW
Another edge-case EF Core scenario.
另一个边缘情况 EF Core 场景。
Check you have a Migrations/YOURNAMEContextModelSnapshot.csfile.
检查您是否有Migrations/YOURNAMEContextModelSnapshot.cs文件。
as detailed in - https://docs.microsoft.com/en-us/ef/core/managing-schemas/migrations/#create-a-migration
如详细信息 - https://docs.microsoft.com/en-us/ef/core/managing-schemas/migrations/#create-a-migration
If you have tried to manually re-create your database by deleting migration.cs files, be careful that your Migrations/*ContextModelSnapshot.cs file still exists.
如果您尝试通过删除 migration.cs 文件手动重新创建数据库,请注意您的 Migrations/*ContextModelSnapshot.cs 文件仍然存在。
Without it, your subsequent migrations have no snapshot on which to create the required differences and your new migrations files will look like they are re-creating everything again from scratch, you will then get the existing table error as above.
没有它,您的后续迁移将没有快照来创建所需的差异,并且您的新迁移文件看起来像是从头开始重新创建所有内容,然后您将获得上述现有表错误。
回答by Chekusty
In my case, the issue was in Seeder. I was calling _ctx.Database.EnsureCreated() inside of it and as far as I understood, the update database command has successfully executed, but then seeder tried to create database "second" time.
就我而言,问题出在 Seeder 中。我在其中调用 _ctx.Database.EnsureCreated() ,据我所知,更新数据库命令已成功执行,但随后播种机尝试“第二次”创建数据库。
How to address:
如何解决:
- Do nut run update, just start application and call EnsureCreated(). Database will be created/updated
- Comment out or remove seeder.
- 不要运行更新,只需启动应用程序并调用EnsureCreated()。将创建/更新数据库
- 注释掉或删除播种机。