【问题标题】:Entity Framework Code First unique index foreign key throws DbUpdate Exception实体框架代码第一个唯一索引外键抛出 DbUpdate 异常
【发布时间】:2016-03-02 11:54:41
【问题描述】:

这是实体和上下文代码:

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();
}

结果,我得到了这个错误:

未处理的类型异常 'System.Data.Entity.Infrastructure.DbUpdateException' 发生在 EntityFramework.dll 无法在对象中插入重复的键行 具有唯一索引“MemberUniqueIndex”的“dbo.Members”。重复键 值为(约翰,史密斯)。声明已终止。

奇怪的是,如果我在添加示例的同时运行该方法,该方法可以正常工作并按预期设置 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();
}

但这会产生一个新问题:

“违反PRIMARY KEY约束'PK_dbo.Members'。无法插入 对象“dbo.Members”中的重复键。重复键值为 (0)。\r\n语句已终止。"

我使用的值是 1 和 3 (bicycle_set_FK(1, 3);)。成员包含 3 行 ID:1、2 和 3。那么它在哪里找到零,因为它不在数据库中,我也没有在代码中的任何位置输入它?

还有一件事:这篇文章没有提到如何在一对多的关系中解决这个问题。如何在 Family 和 Member 之间添加 FK?我是否添加了一些属性,例如public List&lt;Member&gt; FamilyMembersFK

【问题讨论】:

    标签: c# entity-framework ef-code-first entity-framework-6 foreign-key-relationship


    【解决方案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();
    

    【讨论】:

    • 我已按照您的指示进行操作,但不幸的是它们导致了更多问题。在我的帖子中查看编辑
    • 查看编辑。您正在处理 2 个问题。首先,让您的模型正确,然后您可以处理 CRUD 代码和存储库。有很多选择。
    猜你喜欢
    • 2012-05-23
    • 2014-06-03
    • 2012-11-29
    • 1970-01-01
    • 1970-01-01
    • 2012-10-20
    • 2012-11-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多