2014-07-04 23 views
0

我正在使用現有數據庫的代碼優先遷移。我使用逆向工程功能來生成所有的初始實體。但是,數據庫設計不好,其中一個表沒有指定主鍵。顯然實體框架盡力推斷主鍵,並沒有把它做對。它看起來像決定讓兩個字段成爲複合主鍵。如何修復由實體框架生成的代碼中的錯誤

我想實際刪除它誤認爲是主鍵的一部分的字段之一,並導致錯誤。

下面是表的原始模式的實體是爲它創建時:

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_IDField_5成複合主鍵。至少我是這樣解釋這段代碼的。現在,我實際上需要從表格中刪除Field_5。我創建了一個遷移來執行此操作,但是由於實體框架認爲它是主鍵的一部分,因此它會執行一些奇怪的操作,如放棄主鍵並重新添加它,這會導致錯誤。下面是生成的遷移代碼:

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' is not a constraint.

那麼,如何讓自己擺脫這種混亂?

我試圖從The_IDField_5去除[Key]屬性和創建使用

Add-Migration dummy -IgnoreChanges

與想法,我可以再添加[Key]屬性回到The_ID和刪除Field_5一個虛擬的遷移,但它不會讓我創建一個遷移,除非至少有一個字段用[Key]屬性指定。但是如果我這樣做來實現虛擬遷移,那麼我不能在真正的遷移中實現這一點,所以我無法實際指定The_ID作爲使用代碼優先遷移的主鍵。

任何想法?

+0

什麼是理想的結果。您是否希望Fild_5被刪除,並且正在創建the_id上​​的主鍵? – codeworx

+0

是的,這正是我想要的。 – d512

回答

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"); 
} 
+0

謝謝,這基本上是我最終做的。我只是不確定修改自動生成的遷移是否可行。但我想這只是代碼,除非我明確告訴系統重新生成它,否則它不會改變。 – d512

+0

更改遷移非常好。有時你應該這樣做。如果重命名Property/Column Add-Migration可能會創建DropColumn/AddColumn遷移。手動將其更改爲RenameColumn。還可以手動完成一些額外的索引。生成的遷移或多或少只是一個建議 – codeworx

相關問題