0

這裏的的entites和上下文代碼:實體框架代碼優先唯一索引外鍵拋出的dbupdate異常

public class Family 
{ 
    public int FamilyID { get; set; } 
    public String address { get; set; } 
    public virtual ICollection<Member> FamilyMembers { get; set; } 
} 
public class Member 
{ 
    [Index("MemberUniqueID", IsUnique = true)] 
    public int MemberID { get; set; } 

    [StringLength(50)] [Index("MemberUniqueIndex", 1, IsUnique = true)] 
    public String name { get; set; } 
    [StringLength(50)] [Index("MemberUniqueIndex", 2, IsUnique = true)] 
    public String surname { get; set; } 

    public int age { get; set; } 
    public int FamilyID { get; set; } 
    public virtual Family Family { get; set; } 
} 
public class Bicycle 
{ 
    public int BicycleID { get; set; } 
    public virtual Member Owner { get; set; } 
} 
public class MyContext : DbContext 
{ 
    public MyContext : base() { } 
    public DbSet<Member> MemberDB { get; set; } 
    public DbSet<Family> FamilyDB { get; set; } 
    public DbSet<Bicycle> BicycleDB { get; set; } 
} 

現在,我添加的每個的幾個例子,它們添加和SaveChanges();。然後我嘗試運行這段代碼:

public void bicycle_set_FK(int IDbicycle, int IDmember) 
{ 
     var bicycleToFind = BicycleDB.Find(IDbicycle); 
     var memberToSetAsFK = MemberDB.Find(IDmember); 
     bicycleToFind.Owner = memberToSetAsFK; 
     SaveChanges(); 
} 

而作爲一個結果,我得到這個錯誤:

An unhandled exception of type 'System.Data.Entity.Infrastructure.DbUpdateException' occurred in EntityFramework.dll Cannot insert duplicate key row in object 'dbo.Members' with unique index 'MemberUniqueIndex'. The duplicate key value is (John, Smith). The statement has been terminated.

奇怪的是,如果我同時運行的方法,同時增加的例子中,該方法工作正常,並按預期設置FK。但是,如果我首先將代碼添加到代碼的第一次運行中,並且嘗試在代碼的第二次運行中設置FK,則會引發該異常。

編輯:

好了,所以我的建議做,讀條每頁之後,你掛我有這樣的:

[ForeignKey("MemberID")] 
public int? OwnerID { get; set; } 
public virtual Member MemberID { get; set; } 

,並且該方法是這樣的:

public void bicycle_set_FK(int IDbicycle, int IDmember) 
{ 
    var bicycleToFind = BicycleDB.Find(IDbicycle); 
    bicycleToFind.MemberID = null; 
    bicycleToFind.OwnerID = IDmember; 
    SaveChanges(); 
} 

但這會產生一個新問題:

"Violation of PRIMARY KEY constraint 'PK_dbo.Members'. Cannot insert duplicate key in object 'dbo.Members'. The duplicate key value is (0).\r\nThe statement has been terminated."

我使用的值是1和3(bicycle_set_FK(1, 3);)。成員包含3行ID:1,2和3.那麼它在哪裏找到零,因爲它不在數據庫中,也不會在代碼中的任何點輸入它?

還有一件事:文章沒有提到如何在一對多的關係中解決這個問題。如何在Family和Member之間添加FK?我是否添加一些物業,如public List<Member> FamilyMembersFK

回答

1

實體框架重新添加您的所有者(成員)。有一對夫婦的解決這個辦法,但因爲你有FK試試這個:

public class Bicycle 
{ 
    public int BicycleID { get; set; } 

    public int MemberID { get; set; } // You can call this ownerId, but then you need to setup the relationship with annotation or fluent 
    public virtual Member Owner { get; set; } 
} 

public void bicycle_set_FK(int IDbicycle, int IDmember) 
{ 
    var bicycleToFind = BicycleDB.Find(IDbicycle); 
    // var memberToSetAsFK = MemberDB.Find(IDmember); ** Don't need to do this since you have FK ** 
    bicycleToFind.MemberId = IDmember; 
    SaveChanges(); 
} 

https://msdn.microsoft.com/en-us/magazine/dn166926.aspx?f=255&MSPPError=-2147217396

編輯:首先,我強烈建議命名您的導航類和鍵,當你遵循一些約定。你正在調用你的導航類「MemberId」 - 這是非常混亂的。如果你想在FK被OWNERID,去這樣的:

public int? OwnerID { get; set; } 

[ForeignKey("OwnerID")] 
public virtual Member Owner { get; set; } 

其次,你不需要這個註解:

//[Index("MemberUniqueID", IsUnique = true)] **MemberID will be a identity key by default so it will have a unique index created. 
public int MemberID { get; set; } 

現在你可以插入現有的擁有者是這樣的:

public void bicycle_set_FK(int IDbicycle, int IDmember) 
{ 
    var bicycleToFind = BicycleDB.Find(IDbicycle); 
    bicycleToFind.OwnerID = IDmember; // Don't worry about the nav class, just set the FK 
    SaveChanges(); 
} 

關於一對多,您已經有配置有:

public virtual ICollection<Member> FamilyMembers { get; set; } 

所以要添加一個新成員:

var newMember = new Member { 
    Name = "Joe", 
    Surname = "Smith", 
    Age = 30, 
    FamilyId = familyId 
}; 

context.Members.Add(newMember); 
SaveChanges(); 
+0

我按照您的指示,但不幸的是他們造成更多的問題。請參閱我的文章中的編輯 – Amai

+0

請參閱編輯。你正在處理2個問題。首先,讓你的模型正確,然後你可以處理CRUD代碼和存儲庫。許多選項可用。 –