2017年6月2日 星期五

【Entity Framework】發現物件名稱 'dbo.TableName' 和索引名稱 'IX_PropertyName' 的重複索引鍵

Code first 更新 DB 時發生
發現物件名稱 'dbo.TableName' 和索引名稱 'IX_PropertyName' 的重複索引鍵,CREATE UNIQUE INDEX 陳述式已結束。重複的索引鍵值為 ()。

這個錯誤訊息的意思是欲作為索引的欄有資料重複,所以沒辦法建立索引,我第一時間的反應超困惑,因為那欄我沒有任何重複資料阿?

我出錯的地方在我想把 table Member 的 column Mail 正名成 Email,Mail 本來已經設不重複了,所以我直覺反應怎麼會換個名字就有重複資料? 而且重複部分又沒秀,給我一個() 是怎樣?

public override void Up()
{
    DropIndex("dbo.Member", new[] { "Mail" });
    AddColumn("dbo.Member", "Email", c =< c.String(nullable: false, maxLength: 255));
    CreateIndex("dbo.Member", "Email", unique: true);
    DropColumn("dbo.Member", "Mail");
    DropColumn("dbo.Member", "IsActive");
}
實際觀察升版的行為會發現,他是先加 Email,然後就做 Index,也就是說所有的 Email 會先通通被賦予 null,這個時候要做 Index 就會造成 null 跟 null 重複,也解釋了為什麼重複值吐一個()給我。

解決
public override void Up()
{
    DropIndex("dbo.Member", new[] { "Mail" });
    AddColumn("dbo.Member", "Email", c =< c.String(nullable: false, maxLength: 255));
    Sql("UPDATE dbo.Member SET Email = Mail"); // update ori to new before make index
    CreateIndex("dbo.Member", "Email", unique: true);
    DropColumn("dbo.Member", "Mail");
    DropColumn("dbo.Member", "IsActive");
}
在做 index 前先把舊的 Mail 寫給 Email 就好了。

ref: SO

沒有留言:

張貼留言