Използвам първи миграции на код със съществуваща база данни. Използвах функцията за обратно инженерство, за да генерирам всички първоначални обекти. Базата данни обаче не беше добре проектирана и една от таблиците нямаше зададен първичен ключ. Очевидно 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");
}
Изпълнението на това води до следната грешка:
ALTER TABLE [dbo].[Table1] DROP CONSTRAINT [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 като първичен ключ, използвайки миграции на кода първи.
Някакви идеи?