74

Ошибка обновления базы данных из консоли диспетчера пакетов. Я использовал 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> 
+0

Как это сделать (сопоставление существующего проекта)? – Jahan

+15

@HLGEM. Если «хорошо продуманная база данных» может быть сопоставлена ​​с объектной моделью с использованием EF, то EF также может ее сгенерировать. Переходы с БД - это мощный инструмент, облегчающий развертывание вашей базы данных. Я бы не рекомендовал избегать использования миграции DB. В любом случае, скрипты исправления необходимы. Я бы рекомендовал правильно использовать миграцию БД. –

ответ

92

, кажется, есть проблема в процессе миграции, запустить надстройку миграции в "Package Manager Console" :

Add-Migration Initial -Ignor Echanges

сделать некоторые изменения, а затем обновить базу данных "Initial" файла:

Update-Database -verbose

+6

Что это делает? Означает ли это, что новая модель может просто перезаписать старый? –

+1

Я начал использовать ручные миграции, потому что я использую Views, а также таблицы в моей базе данных.Я сделал ошибку, пытаясь использовать автоматические миграции, и в результате попытался создать таблицу из представления. В этом случае ваше решение не работает, вместо этого я всегда должен использовать ручные миграции. Поэтому после этого мне пришлось отменить изменения в контроле источника и удалить запись «Initial» из таблицы _Migrations. – arame3333

+0

хорошая работа, это сработало для меня :) –

17

«Существует уже объект с именем 'ABOUTUS' в базе данных ".

В этом исключении указано, что кто-то уже добавил объект с именем «AboutUs» в базу данных.

AutomaticMigrationsEnabled = true; может привести к этому, поскольку версии базы данных не контролируются вами в этом случае. Во избежание непредсказуемых миграций и убедитесь, что каждый разработчик в команде работает с той же базой данных Предлагаю вам установить AutomaticMigrationsEnabled = false;.

Автоматические миграции и закодированные миграции могут жить вместе, если вы очень осторожны и являетесь единственным разработчиком проекта.

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

Автоматические Миграции позволяет использовать код сначала Миграции без имея файл кода в проекте для каждого изменения вы делаете. Не все изменения могут применяться автоматически - например, переименования столбцов требуют использования миграции на основе кода.

Рекомендация для команды Environments

Вы можете пересыпать автоматические и на основе кода миграции, но это не рекомендуется использовать в сценариях развития команды. Если вы являетесь частью команды разработчиков , которые используют источник управления, вы должны либо использовать чисто автоматические миграции, либо просто переносить на основе кода. Учитывая ограничения автоматической миграции на , мы рекомендуем использовать на основе кода миграции в командных средах.

+1

Спасибо, очень хороший совет. –

4

Убедитесь, что ваш проект запуска решений имеет правильную строку подключения в файле конфигурации. Или задайте параметр -StartUpProjectName при выполнении команды update-database. Параметр -StartUpProjectName указывает файл конфигурации, который будет использоваться для названных строк подключения. Если этот параметр опущен, используется файл конфигурации указанного проекта.

Вот ссылка для ссылок команд эф-миграции http://coding.abel.nu/2012/03/ef-migrations-command-reference/

+0

Этот ответ привел меня к моей ошибке, у меня просто был неправильный проект как проект Startup. –

0

Удаление строк из dbo_MigrationHistory таблицы или удалить таблицу и запустить

update-database -verbose 

Он будет работать все миграции в проекте по одному

4

В моем случае я переименовал сборку, содержащую модель фреймворка сущности кода. Хотя фактическая схема не изменилась вообще таблицы кочевок называется

dbo.__MigrationHistory 

содержит список уже выполненных миграций на основе имени сборки старого. Я обновил старое имя в таблице миграции, чтобы соответствовать новому, а затем снова перенастроен.

-4

В файле миграции проверьте public override void Up(). Возможно, вы пытаетесь создать новый объект db, который уже находится в базе данных. Итак, вам нужно отбросить этот объект/таблицу перед созданием объекта db. Просто сделай, как bellow-

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

А теперь запустить перенастройки Update-Database -TargetMigration: "2016_YourMigration"

+4

Если вы сделаете это, вы потеряете все свои данные – Mehdiway

48

Может быть, вы изменили пространство имен в вашем проекте!
В вашей базе данных есть таблица dbo.__MigrationHistory. Таблица имеет столбец под названием ContextKey.
Значение этой колонки основано на вашем namespace. например, «DataAccess.Migrations.Configuration».
При изменении пространства имен это приводит к дублированию имен таблиц с разными пространствами имен.
Итак, после того, как вы измените пространство имен на стороне кода, измените пространство имен в этой таблице и в базе данных (для всех строк).
Например, если вы изменили пространство имен на EFDataAccess, то вы должны изменить значения столбца ContextKey в dbo.__MigrationHistory на «EFDataAccess.Migrations.Configuration».
Затем в кодовой части в Инструменты => Консоль диспетчера пакетов используйте команду update-database.

Другим вариантом вместо изменения значения контекста в базе данных является жесткое кодирование значения контекста в вашем коде для старого значения пространства имен. Это возможно, наследуя DbMigrationsConfiguration<YourDbContext>, а в конструкторе просто назначьте значение старого контекста ContextKey, чем наследуйте от MigrateDatabaseToLatestVersion<YourDbContext, YourDbMigrationConfiguration> и оставьте этот класс пустым. Последнее, что нужно сделать, это вызвать Database.SetInitializer(new YourDbInitializer()); в вашем DbContext в статическом конструкторе.

Надеюсь, ваша проблема будет исправлена.

+4

Удивительно, у нас была именно эта проблема! –

+1

На самом деле это настоящая причина этой ошибки. EF пытается создать базу данных, так как не может читать, какие миграции, которые применяются к базе данных, из-за разницы в названии пространства. – UfukSURMEN

+0

Спасибо. Это сработало и для меня! – naffie

1

Примечание: не рекомендуется решение. но быстро исправить в некоторых случаях.

Для меня dbo._MigrationHistory в производственной базе данных пропущены записи миграции во время процесса публикации, но база данных разработки имела все записи миграции.

Если вы уверены, что у производственной базы данных есть такая же и новейшая схема по сравнению с dev db, скопируйте все записи миграции в производственную базу данных, чтобы решить проблему.

Вы можете делать только в VisualStudio.

  1. Открыть панель «SQL сервер объектов Explorer»> правой кнопкой мыши dbo._MigrationHistory таблицу в источнике (в моем случае DEV дб) базы данных> Нажмите «Данные сравнения ...» меню.
  2. Затем появится мастер сравнения данных, выберите целевую базу данных (в моем случае производственная база данных) и нажмите «Далее».
  3. Через несколько секунд он отобразит некоторые записи только в исходной базе данных. просто нажмите кнопку «Обновить цель».
  4. В браузере нажмите кнопку обновления и увидите сообщение об ошибке.

Обратите внимание, что это не рекомендуется в сложных и серьезных проектах. Используйте это только у вас есть проблемы во время обучения ASP.Net или EntityFramework.

2

В моем случае, мой EFMigrationsHistory стол опустел (как-то), и при попытке запустить update-database я хотел бы получить:

Существует уже объект с именем «AspNetUsers» в базе данных

Увидев, что стол был опустошен, имело смысл, что он пытался перезапустить начальную миграцию и попытаться воссоздать таблицы.

Чтобы устранить эту проблему, я добавил строки в таблицу EFMigrationsHistory. 1 строка для каждой миграции, с которой я знал, что база данных обновлена.

Строка будет иметь 2 колонки: MigrationId и ProductVersion

MigrationId это имя файла миграции. Пример: 20170628112345_Initial

ProductVersion - это версия ef, в которой вы работаете. Вы можете найти это, введя Get-Package в консоль диспетчера пакетов и ищите свой пакет ef.

Надеюсь, это поможет кому-то.

Смежные вопросы