Как да коригирате грешка в кода, генериран от Entity Framework

Използвам първи миграции на код със съществуваща база данни. Използвах функцията за обратно инженерство, за да генерирам всички първоначални обекти. Базата данни обаче не беше добре проектирана и една от таблиците нямаше зададен първичен ключ. Очевидно 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 като първичен ключ, използвайки миграции на кода първи.

Някакви идеи?


person d512    schedule 04.07.2014    source източник
comment
Какъв е желаният резултат. Кой искате Fild_5 да бъде премахнат и да бъде създаден първичен ключ на the_id?   -  person codeworx    schedule 04.07.2014
comment
Да, точно това искам.   -  person d512    schedule 05.07.2014


Отговори (1)


Ако имате таблица без първичен ключ във вашата база данни, EntityFramework ще интерпретира всяка колона в таблицата, която не може да бъде нулева, като част от първичния ключ.

В този случай можете просто да премахнете първите два реда от генерираната миграция, тъй като няма първичен ключ за премахване. 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");
}
person codeworx    schedule 07.07.2014
comment
Благодаря, в крайна сметка това е, което направих. Просто не бях сигурен дали модифицирането на автоматично генерирана миграция е добре да се направи. Но предполагам, че това е само код и не е като да се промени, освен ако изрично не кажа на системата да го регенерира. - person d512; 08.07.2014
comment
Промяната на миграциите е напълно наред. Понякога трябва да го направите. Ако преименувате Property/Column Add-Migration може да създаде миграция DropColumn/AddColumn. Променете го ръчно на RenameColumn. Също така добавянето на някои допълнителни индекси може да се извърши ръчно. Генерираната миграция е повече или по-малко само предложение - person codeworx; 09.07.2014