简体   繁体   中英

multiple added entities may have the same primary key for some cyclic entity

I have some cyclic entity, want to save all the details of EntityA by attaching navigation objects like Entity B and EntityC, but when it try to save getting "multiple added entities may have the same primary key error". Ids in all the table are identity. Basically I want a reference of A and B in table C and reference of A in B.`

 

     public class EntityA
    {
        [Key]
        public int QID { get; set; }
    
        public virtual List<EntityC> EntityCs { get; set; }
    
        public virtual List<EntityB> EntityBs { get; set; }
    }
    
    public class EntityB
    {
        [Key]
        public int OptionID { get; set; }
        public int QID { get; set; }
        [ForeignKey("QID")]
        public virtual EntityA EntityA { get; set; }
    }
       
    
     public class EntityC
     {
                [Key]
                public int CID { get; set; }
                public int QID { get; set; }
                public int OptionID { get; set; }
                [ForeignKey("QID")]
                public virtual EntityA EntityA { get; set; }
                [ForeignKey("OptionID")]
                public virtual EntityB Option { get; set; }
      }

Make sure you are adding the same tracked instance reference. This type of error is commonly cause when developers assume that two instances with the same ID are interpreted as pointing at the same record so EF will know they are the same thing.

For instance: (Error)

var b = new B { Id = bId, A = new A { Id = aId }};
var c = new C { Id = cId, A = new A { Id = aId }};
context.Bs.Add(b);
context.Cs.Add(c);

bA and c.A point to 2 separate instances of an "A" record. (same ID but different instances) EF will encounter this as 2 new A records and try to insert both.

Assuming the "A" in this case is a new record as well:

var a = new A { Id = aId };
var b = new B { Id = bId, A = a };
var c = new C { Id = cId, A = a };
context.Bs.Add(b);
context.Cs.Add(c);

The key difference in this example is that we instantiate a new single instance of an "A" and then reference that in our new B and C. When the Context tracks this, they will be pointing to the same instance.

If, however, the A instance should already exist in the database, and possibly tracked by the DbContext even:

var a = context.As.Single(a => a.Id == aId);
var b = new B { Id = bId, A = a };
var c = new C { Id = cId, A = a };
context.Bs.Add(b);
context.Cs.Add(c);

This ensures that the A reference that the context should know about as an existing record is loaded and used in the new B and C references. If you create a new A even using an ID that already exists, adding that to the Context directly or indirectly through a new B or C will cause EF to treat it as a new record and try to insert it. This will result in duplicate PK errors, or worse, silent issues if the IDs are set up as Identity columns as it can insert new "A" records with new IDs that you don't expect.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM