Entity Framework code-first: миграция завершается неудачей с помощью базы данных обновлений, что приводит к ненужному (?) Добавлению-миграции
У меня есть забавный эффект, используя миграцию (EF 5.0) и первый код:
Я создал несколько моделей с первичными ключами GUID. (Кстати: для меня важно, чтобы SQL Server использовал NEWSEQUENTIALID()
, который, по-видимому, является значением по умолчанию в текущей версии)
В какой-то момент я активировал миграции. Я добавил некоторый код в начальную миграцию, в основном это .Index()
мере необходимости.
Когда я удаляю базу данных и вызываю update-database, я получаю следующую ошибку:
Невозможно обновить базу данных в соответствии с текущей моделью, поскольку есть ожидающие изменения и автоматическая миграция отключена. Либо запишите ожидающие изменения модели в миграцию на основе кода, либо включите автоматическую миграцию. Установите в DbMigrationsConfiguration.AutomaticMigrationsEnabled значение true, чтобы включить автоматическую миграцию. Вы можете использовать команду Add-Migration для записи ожидающих изменений модели в миграцию на основе кода.
Я попытался AutomaticMigrationsEnabled = true
, который работал без изменения или добавления чего-либо!
Но так как я не хочу AutomaticMigrationsEnabled
, я также попытался снова удалить базу данных, которая называется update-database
и затем add-migration
. Я закончил с дополнительной миграцией, которая, кажется, ничего не меняет (см. Ниже). Я также попытался добавить эти строки в конец начальной миграции, но это ничего не меняет.
Одна из моделей:
[Table(Speaker.TABLENAME)]
public class Speaker : BaseModel
{
public const String TABLENAME = "Speaker";
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
[Required]
[MaxLength(50, ErrorMessage = "Name must be 50 characters or less")]
public string Name { get; set; }
}
Исходный код миграции:
public partial class InitialCreate : DbMigration
{
public override void Up()
{
// [...]
CreateTable(
"dbo.Speaker",
c => new
{
Id = c.Guid(nullable: false, identity: true),
Name = c.String(nullable: false, maxLength: 50),
})
.PrimaryKey(t => t.Id)
.Index(t => t.Name, true, false); // added manually: unique Name
// [...]
}
}
internal sealed class Configuration : DbMigrationsConfiguration<MyProject.Repositories.DBContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
}
protected override void Seed(MyProject.Repositories.DBContext context)
{
// ...
}
}
Ниже приведен код, созданный с помощью add -igration: похоже, он ничего нового не делает - может быть, я что-то упустил?
public partial class UnneccessaryMigration : DbMigration
{
public override void Up()
{
// isn't this the exact same code from InitialMigrations?
AlterColumn("dbo.Speaker", "Id", c => c.Guid(nullable: false, identity: true));
// ...
}
public override void Down()
{
//...
AlterColumn("dbo.Speaker", "Id", c => c.Guid(nullable: false));
}
}
Поэтому мне любопытно: что я сделал, чтобы дезориентировать миграции? И что я могу сделать, чтобы заставить его работать только с одной начальной миграцией?
Решение: Следующий обходной путь сделал это для меня:
- Я удалил базу данных и все миграции, как описано здесь: qaru.site/info/28073/...
- Выполнено Enable-Migrations + Add-Migration Initial
- Слил мои изменения .Index() ручной работы в файл. Теперь Update-Database работает снова - также многократно, при удалении базы.
Ответы
Ответ 1
Я также попытался снова удалить базу данных, называемую базой обновлений и затем добавьте-миграцию. Я закончил с дополнительной миграцией, которая кажется не изменять ничего (см. ниже)
Основываясь на данных выше, я думаю, что вы сделали последнее в первую очередь. Если вы запустите Update database
до Add-migration
, он не обновит базу данных вашими схемами миграции. Сначала вам нужно добавить миграцию, а затем запустить команду обновления.
Попробуйте их в этом порядке с помощью консоли диспетчера пакетов.
PM> Enable-migrations //You don't need this as you have already done it
PM> Add-migration Give_it_a_name
PM> Update-database
Ответ 2
У Entity Framework есть некоторые проблемы, связанные с полями идентичности.
Вы не можете добавить идентификатор GUID в существующую таблицу
Миграции: не обнаруживает изменений в DatabaseGeneratedOption
Обратное проектирование не маркирует GUID-ключи по умолчанию NEWSEQUENTIALID() как созданные хранилищем идентификаторы
Ни один из них не описывает вашу проблему точно, и метод Down() в вашей дополнительной миграции интересен, поскольку, похоже, пытается удалить IDENTITY из столбца, когда появляется CREATE TABLE в начальной миграции для его установки!
Кроме того, если вы используете Update-Database -Script
или Update-Database -Verbose
для просмотра sql, запускаемого из этих методов AlterColumn
, вы увидите, что sql идентичен в Up
и Down
, и фактически ничего не делает. ИДЕНТИФИКАЦИЯ остается неизменной (для текущей версии - EF 6.0.2 и ниже) - как описано в первых двух проблемах, с которыми я связан.
Я думаю, вы должны удалить избыточный код в своей дополнительной миграции и жить с пустой миграцией на данный момент. И вы можете подписаться на голосование по вопросам, которые будут рассмотрены.
Литература:
Изменить параметр IDENTITY делает dodly squat
Включение/выключение идентификации идентификации с помощью пользовательской миграции
Ответ 3
Попробуй это:
PM> Enable-migrations -force
PM> Add-migration MigrationName
PM> Update-database -force
Ответ 4
для меня я решил это следующим образом В Visual Studio 2015: В меню "Вид" выберите "Другие окна", затем "Консоль диспетчера пакетов" и выполните следующие команды:
PM> enable-migrations
Миграции уже включены в проекте mvcproject. Чтобы перезаписать существующую конфигурацию миграции, используйте параметр -Force.
PM> enable-migrations -Force
Проверка, нацелен ли контекст на существующую базу данных... Включены первые миграции кода для проекта mvcproject.
затем добавьте имя миграции в папку миграции, он добавит нужный класс в обозревателе решений, выполнив следующую команду
PM>Add-migration AddColumnUser
Наконец обновите базу
PM> update-database
Ответ 5
При использовании VS2019, MVC5 - найдите в папке Migrations файл Configuration.cs Edit: AutomaticMigrationsEnabled = true
Ответ 6
Выполните следующие шаги 1. Просто удалите папку "Миграции" в своем проекте. 2. Очистите раствор. 3. Затем в консоли диспетчера пакетов выполните следующие команды одну за другой: o Enable-migrations (если у вас более одного файла контекста, вам, возможно, придется указать, какой из них нужно обновить. Но это легко, как покажет VS2019 что красным) o Начальная миграция добавления o Обновление базы данных
Ответ 7
В ответ на ваш общий вопрос
Поэтому мне любопытно: что я сделал, чтобы дезориентировать миграции? И что я могу сделать, чтобы это работало только с одной начальной миграцией?
Я только что получил то же сообщение об ошибке, что и вы, после объединения нескольких веток, и миграция запуталась в текущем состоянии базы данных. Хуже всего то, что это происходило только на клиентском сервере, а не в наших системах разработки.
Пытаясь понять, что там происходит, я наткнулся на это превосходное руководство Microsoft:
Руководство Microsoft по Code First Migrations в командной среде
Хотя это руководство было написано для объяснения миграций в группах, оно также дает лучшее объяснение того, как миграции работают внутри компании, что может привести к объяснению поведения, которое вы видите. Для тех, кто работает с EF6 или новее, стоит потратить целый час, чтобы прочитать все это.
Для любого, кто задал этот вопрос сообщением об ошибке после слияния миграций, уловка генерации пустой миграции с текущим состоянием базы данных решила для меня кое-что, но не забудьте прочитать все руководство полностью знать, подходит ли это решение в вашем случае.
Ответ 8
У меня была эта проблема, и приведенные выше предложения не помогли. Я обнаружил, что add -igration считывает текущее состояние и создает сигнатуру текущей модели. Вы должны изменить свою модель перед изменением. Итак, последовательность такова.
- Изменить модель
- запустить add -igration
Я сделал обратное и добавил миграцию перед изменением моей модели (которая была пустой, поэтому я добавил новые столбцы), а затем запустил свой код.
Надеюсь это поможет.