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代码和存储库。许多选项可用。 –