这里是entites和上下文代码:
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();
}
结果,我收到了这个错误:
未处理的类型异常 &#39; System.Data.Entity.Infrastructure.DbUpdateException&#39;发生在 EntityFramework.dll无法在对象中插入重复的键行 &#39; dbo.Members&#39;具有唯一索引&#39; MemberUniqueIndex&#39;。重复的密钥 价值是(约翰,史密斯)。声明已经终止。
奇怪的是,如果我在添加示例的同时运行该方法,该方法可以正常工作并按预期设置FK。但是,如果我首先在第一次运行代码时添加示例,并尝试在第二次运行代码时设置FK,则会抛出该异常。
好的,所以我已经按照建议完成了,在阅读了你关联的artice之后我就有了这个:
[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();
}
但这会产生一个新问题:
&#34;违反PRIMARY KEY约束&#39; PK_dbo.Members&#39;。无法插入 对象&#39; dbo.Members&#39;中的重复键。重复的键值是 (0)。\ r \ n该声明已被终止。&#34;
我使用的值是1和3(bicycle_set_FK(1, 3);
)。成员包含3行ID:1,2和3.那么它在哪里找到零,因为它不在数据库中,也不在代码中的任何一点输入它?
还有一件事:文章没有提到如何在一对多的关系中解决这个问题。如何在家人和会员之间添加FK?我是否添加了一些属性,例如public List<Member> FamilyMembersFK
?
答案 0 :(得分: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();