2015-10-17 81 views
2

我有一個代碼,第一EF模型是這樣的:實體框架外鍵插入重複鍵

public partial class A 
{ 
    [Key] 
    [StringLength(7)] 
    public string Code { get; set; } 

    [Required] 
    [StringLength(100)] 
    public string Name { get; set; } 


    public virtual ICollection<B> Bs { get; set; } 
} 

public partial class B 
{ 
    [Key] 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public int Id { get; set; } 

    [Required] 
    [StringLength(100)] 
    public string Name { get; set; } 

    [Required] 
    [StringLength(7)] 
    [ForeignKey("A")] 
    public string ACode { get; set; } 

    public virtual A A { get; set; } 
} 

當我將這樣的數據:

var a = new A(); 
a.Code = "A0"; 
a.Name = "A Name"; 

var b = new B(); 
b.Name = "B Name"; 
b.ACode = a.Code; 
b.A = a; 

using (DbContext context = new DbContext()) 
{ 
     context.As.Add(a); 
     context.Bs.Add(b); 
     context.SaveChanges(); 
} 

var b2 = new B(); 
b2.Name = "B Name 2"; 
b2.ACode = a.Code; 
b2.A = a; 

using (DbContext context = new DbContext()) 
{ 
     context.Bs.Add(b2); 
     context.SaveChanges(); 
} 

我在第一context.SaveChanges沒問題。但是,當我嘗試添加b2相同ACode和參考我得到

違反PRIMARY KEY約束'PK_dbo.As'。不能在對象'dbo.As'中插入重複鍵。重複的鍵值是(A0)。

我真的很困惑的是這樣做,我會很高興,如果有人可以解釋爲什麼在第二次調用context.SaveChanges(),EF試圖插入而不是使用現有的一個新的A實體。

非常感謝您的幫助

+0

第一次SaveChanges後,A有一個Id值。因爲你在第二次調用中隱式添加了相同的對象,所以你會得到異常。您應該保持上下文打開或將A的狀態設置爲已修改。 – DevilSuichiro

+0

A沒有ID,密鑰應該是代碼。每當我想將實體B添加到數據庫時,我都無法擁有相同的上下文。我希望能夠隨時引用實體B,而不僅僅是當我將實體A插入數據庫時​​。 – Teamol

+0

第二個上下文對'a'沒有理解,它假定應該加上'a',因此是例外。 –

回答

1

所以感謝王中王的評論,我發現了兩件事情。

首先是我可以自動查找外鍵,如果只有外部標識被分配(不參考)。

var b2 = new B(); 
b2.Name = "B Name 2"; 
b2.ACode = a.Code; 

代替

var b2 = new B(); 
b2.Name = "B Name 2"; 
b2.ACode = a.Code; 
b2.A = a; 

其次是,當你指定參考你要附加的引用對象使用context.As.Attach的(a)之前context.Bs.Add(B2);

非常感謝王國王你的帖子幫助了我很多。