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


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

11 ответов:

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

Add-Migration Initial-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;.

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

есть цитата из сообщения Automatic Code First Migrations на Data Developer Center:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

dbo.__MigrationHistory

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

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

update-database -verbose

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

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

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

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

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

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

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

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

Как адрес:

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

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

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

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

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