В базе данных уже есть объект с именем
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 исключительно.
- открыть ' объект SQL Server Панель проводника > щелкните правой кнопкой мыши
dbo._MigrationHistory
таблица в исходной (в моем случае dev db) базе данных > нажмите "сравнение данных..." меню. - затем появился мастер сравнения данных, выберите целевую базу данных (в моем случае производственная БД) и нажмите кнопку Далее.
- через несколько секунд он покажет некоторые записи только в исходной базе данных. просто нажмите кнопку "Обновить цель".
- в браузере нажмите кнопку "Обновить" и увидите сообщение об ошибке.
обратите внимание, что, опять же, это не рекомендуется в сложных и серьезных проектах. Используйте это только у вас есть проблемы во время ASP.Net или обучение EntityFramework.
в моем случае, проблема была в сеялки. Я звонил _ctx.База данных.EnsureCreated () внутри него и, насколько я понял, команда update database успешно выполнена, но затем сеялка попыталась создать базу данных "второй" раз.
Как адрес:
- do nut run update, просто запустите приложение и вызовите EnsureCreated(). База данных будет создана / обновлена
- Прокомментировать или удалить сеялку.
просто выполните команду 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"