Как исправить ошибку в коде, созданном 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 будет интерпретировать каждый столбец таблицы, не допускающий значения 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");
}
person codeworx    schedule 07.07.2014
comment
Спасибо, в основном то, чем я закончил. Я просто не был уверен, можно ли изменить автоматически созданную миграцию. Но я предполагаю, что это просто код, и он не изменится, если я явно не скажу системе, что нужно его регенерировать. - person d512; 08.07.2014
comment
Смена миграций - это нормально. Иногда вы должны это делать. Если вы переименуете свойство / столбец Add-Migration, может возникнуть миграция DropColumn / AddColumn. Вручную измените его на RenameColumn. Также можно вручную добавить некоторые дополнительные индексы. Сгенерированная миграция - это более или менее всего лишь предложение - person codeworx; 09.07.2014