2017-04-07 29 views
3

編輯:夥計們,我很抱歉,我浪費了你的時間。調試時導致此問題,我錯過了一行代碼。有人提出了一個條件,即檢查數據庫中是否存在該名稱,如果是,則拋出此異常。Enitity Framework錯誤地在多列上強制執行一個唯一的約束條件

我首先使用實體​​框架代碼,並且我有一個實體,它包含一個跨兩列的唯一約束的索引,如下面的代碼所示。 (我改變了屬性的名稱,以普通的東西,以便不顯示任何我公司的代碼庫)

[Table("TB_Table")] 
public class Table : IEntity 
{ 
    [Key] 
    [Column("TBT_RID")] 
    public int Id { get; set; } 

    [ForeignKey("Something")] 
    [Index("idxSomethingTableName", 1, IsUnique = true)] 
    [Column("TBT_SOS_RID")] 
    public int SomethingId { get; set; } 

    [Index("idxSomethingTableName", 2, IsUnique = true)] 
    [MaxLength(255)] 
    [Column("TBT_Name")] 
    public string Name { get; set; } 

    // Navigation properties 
    [JsonIgnore] 
    public virtual Something Something { get; set; } 

    [InverseProperty("Table")] 
    [JsonIgnore] 
    public virtual ICollection<AssetTag> ObjectTables { get; set; } 

} 

當插入SQL中的記錄,唯一約束被正確執行。然後,當試圖通過實體框架輸入記錄時,它告訴我它不能添加具有不同「SomethingId」值但與另一個記錄具有相同「名稱」的記錄。

例如,我可以用SQL插入這些記錄:

insert into TB_Table (TBT_SOS_RID, TGT_Name) values 
(1, 'A'), 
(1, 'B'), 
(30, 'A') 

但我不能添加其他(1, 'A')與SQL。好的,太好了。約束工作正常。現在,如果我試圖用值(30,'B')插入一個使用實體框架的記錄,我應該可以做到這一點,因爲TBT_SOS_RID(C#中的SomethingId)是不同的。相反,我得到一個InvalidOperationException異常,並顯示消息「Invalid table,table already Exists」。在調用SaveChanges()方法之前,這發生在DbSet.Add()方法上。

你可以想到爲什麼實體框架會認爲這是SQL的不唯一約束時違反了嗎?

預先感謝您的時間和幫助解決我的問題。

+0

*無效**表***? –

+0

一切都很好,你的模型的發佈方式 - 我試過了,它的工作原理。必須有一些差異或不正確的用法。需要[mcve]。 –

+1

感謝您的建議/反饋。我試圖在控制檯應用程序中重現此問題,並在此過程中發現導致我的問題的原因。原來,如果名稱已經存在於數據庫中,我錯過了引發此異常的一行代碼。呃...現在我需要弄清楚如何處理這個問題。 –

回答

0

你裝飾名稱如下:

[Index("idxSomethingTableName", 2, IsUnique = true)] 
[MaxLength(255)] 
[Column("TBT_Name")] 
public string Name { get; set; } 

至於實體而言,你已經指出,名稱必須是唯一的,因此,你不能進入這兩個名字是一樣的。

3

看來,克里普託斯回答關於如何處理與外鍵在這裏綜合指數類似的問題:Composite Indices with Foreign Keys

我沒有測試的解決方案,但它可能會幫助引導你沿着正確的方向,擴大對answer by niaher在同一個問題。

+0

謝謝,可愛派。 –