#entity-framework #entity-framework-migrations
#entity-framework #entity-framework-миграции
Вопрос:
Я использую миграции code first с существующей базой данных. Я использовал функцию обратного проектирования для генерации всех исходных объектов. Однако база данных была плохо спроектирована, и в одной из таблиц не был указан первичный ключ. По-видимому, Entity Framework сделала все возможное, чтобы вывести первичный ключ, но не поняла его правильно. Похоже, что было решено сделать два поля составным первичным ключом.
На самом деле я хочу удалить одно из полей, которое он ошибочно считает частью первичного ключа, и это приводит к ошибкам.
Вот исходная схема таблицы, когда для нее была создана сущность:
CREATE TABLE [dbo].[Table1](
[The_ID] [bigint] IDENTITY(1,1) NOT NULL,
[Field_1] [varbinary](max) NULL,
[Field_2] [bigint] NULL,
[Field_3] [varbinary](max) NULL,
[Field_4] [datetime] NULL,
[Field_5] [bit] NOT NULL
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Table1] ADD CONSTRAINT [DF_Table1_F5] DEFAULT ((0)) FOR [Field_5]
GO
The_ID
должен был быть указан в качестве первичного ключа, но, как вы можете видеть, этого не было. Вот класс, созданный Visual Studio:
public partial class Table1
{
[Key]
[Column(Order = 0)]
public long The_ID { get; set; }
public byte[] Field_1 { get; set; }
public long? Field_2 { get; set; }
public byte[] Field_3 { get; set; }
public DateTime? Field_4 { get; set; }
[Key]
[Column(Order = 1)]
public bool Field_5 { get; set; }
}
Очевидно, он решил превратить The_ID
и Field_5
в составной первичный ключ. По крайней мере, так я интерпретирую этот код. Теперь мне действительно нужно удалить Field_5
из таблицы. Я создал миграцию для этого, но поскольку Entity Framework считает свою часть первичным ключом, он делает странные вещи, такие как удаление первичного ключа и его повторное добавление, что приводит к ошибкам. Вот сгенерированный код миграции:
public override void Up()
{
DropPrimaryKey("dbo.Table1");
AlterColumn("dbo.Table1", "The_ID", c => c.Long(nullable: false, identity: true));
AddPrimaryKey("dbo.Table1", "The_ID");
DropColumn("dbo.Table1", "Field_5");
}
Выполнение этого приводит к следующей ошибке:
ИЗМЕНИТЬ ТАБЛИЦУ [dbo].[Table1] УДАЛИТЬ ОГРАНИЧЕНИЕ [PK_dbo.Table1] Исключение System.Data.SqlClient.SQLException (0x80131904): ‘PK_dbo.Table1’ не является ограничением.
Итак, как мне выбраться из этого бардака?
Я попытался удалить [Key]
атрибуты из The_ID
и Field_5
и создать фиктивную миграцию, используя
Добавить фиктивный файл миграции -IgnoreChanges
с мыслью, что я мог бы затем добавить [Key]
атрибут обратно в The_ID
и удалить Field_5
, но это не позволит мне создать миграцию, если хотя бы одно поле не обозначено [Key]
атрибутом. Но если я сделаю это, чтобы запустить фиктивную миграцию, то я не смогу сделать это в реальной миграции, поэтому я не могу фактически назначить the_ID в качестве первичного ключа, используя миграции code first.
Есть идеи?
Комментарии:
1. Каков желаемый результат. Кто бы вы хотели, чтобы Fild_5 был удален и был создан первичный ключ для the_id?
2. Да, это именно то, чего я хочу.
Ответ №1:
Если у вас в базе данных есть таблица без первичного ключа, EntityFramework интерпретирует каждый столбец, не имеющий значения null, в таблице как часть первичного ключа.
В этом случае вы могли бы просто удалить первые две строки из сгенерированного переноса, потому что нет первичного ключа для удаления. EntityFramework просто не знает об этом факте.
public override void Up()
{
//DropPrimaryKey("dbo.Table1");
//AlterColumn("dbo.Table1", "The_ID", c => c.Long(nullable: false, identity: true));
AddPrimaryKey("dbo.Table1", "The_ID");
DropColumn("dbo.Table1", "Field_5");
}
Комментарии:
1. Спасибо, это в основном то, что я закончил делать. Я просто не был уверен, можно ли изменять автоматически сгенерированную миграцию. Но я предполагаю, что это просто код, и не похоже, что он изменится, если я явно не прикажу системе его восстановить.
2. Изменение миграций — это совершенно нормально. Иногда вы должны это делать. Если вы переименуете свойство / столбец Add-Migration, это может привести к миграции DropColumn / AddColumn. Вручную измените его на RenameColumn. Также добавление некоторых дополнительных индексов может быть выполнено вручную. Сгенерированная миграция — это более или менее только предложение