В базе данных уже есть объект с именем

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

11 ответов


кажется, есть проблема в процессе миграции, запустите команду add-migration в "консоль диспетчера пакетов":

Добавить-Начальная Миграция-IgnoreChanges

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

Update-Database-verbose

Edit: - IgnoreChanges находится в EF6, но не в ядре EF, вот обход: https://stackoverflow.com/a/43687656/495455


возможно, вы изменили пространство имен в своем проекте!
В вашей базе данных есть таблица dbo.__MigrationHistory. Таблица имеет столбец с именем ContextKey.
Значение этого столбца основано на вашем namespace. например,"DataAccess.Migrations.Configuration".
при изменении пространства имен возникают повторяющиеся имена таблиц с различными пространствами имен.
Итак, после изменения пространства имен в стороне кода измените пространство имен в этой таблице в базе данных, тоже (для всех строк).
Например, если изменить пространство имен на EFDataAccess, то вы должны изменить значения .

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

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


"в базе данных уже есть объект с именем "AboutUs"."

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

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

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

есть цитата из автоматического кода первого сообщения миграции на Data Developer Center:

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

рекомендация для командных сред

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


в моем случае, мой EFMigrationsHistory таблица была опустошена (как-то) и при попытке запустить update-database Я хотел бы получить:

в базе данных уже есть объект с именем "AspNetUsers"

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

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

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

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

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

надеюсь, что это полезно для кого-то.


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

вот ссылка для команды EF-migration ссылки на литературу http://coding.abel.nu/2012/03/ef-migrations-command-reference/


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

dbo.__MigrationHistory

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


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

update-database -verbose

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


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

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

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

Вы можете сделать в VisualStudio исключительно.

  1. открыть ' объект SQL Server Панель проводника > щелкните правой кнопкой мыши dbo._MigrationHistory таблица в исходной (в моем случае dev db) базе данных > нажмите "сравнение данных..." меню.
  2. затем появился мастер сравнения данных, выберите целевую базу данных (в моем случае производственная БД) и нажмите кнопку Далее.
  3. через несколько секунд он покажет некоторые записи только в исходной базе данных. просто нажмите кнопку "Обновить цель".
  4. в браузере нажмите кнопку "Обновить" и увидите сообщение об ошибке.

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


в моем случае, проблема была в сеялки. Я звонил _ctx.База данных.EnsureCreated () внутри него и, насколько я понял, команда update database успешно выполнена, но затем сеялка попыталась создать базу данных "второй" раз.

Как адрес:

  1. do nut run update, просто запустите приложение и вызовите EnsureCreated(). База данных будет создана / обновлена
  2. Прокомментировать или удалить сеялку.

просто выполните команду update-migration-Script. Это создает новый *.SQL-скрипт, который включает все изменения БД, включенных в миграции. В конце кода находятся команды insert примерно так: INSERT [dbo].[__MigrationHistory] ([MigrationId], [ContextKey], [Model], [ProductVersion]) вы можете просто запустить эту вставку, и DB будет синхронизирован


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

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

а теперь запустите миграцию Update-Database -TargetMigration: "2016_YourMigration"