none
Multiplicity constraint violated on DBContext.SaveChanges() RRS feed

  • Question

  • Hello,

    I have a strange problem using EF 4.3 Code First:

    My Model (Important part of it):

        public class Bauteil : ElementBase, IAdresse {
            //Keys
            public Guid ID { get; set; }

            .....

            public virtual IList<Bauteil> Bauteile {
                get { return _bauteile; }
                set { _bauteile = value; }
            }
            public virtual IList<Dokument> Dokumente {
                get { return _dokumente; }
                set { _dokumente = value; }
            }
        }          

        public class Dokument: ElementBase, IAdresse {
            //Keys
            public Guid ID { get; set; }

            .....

            public virtual IList<Bauteil> Bauteile {
                get { return _bauteile; }
                set { _bauteile = value; }
            }
            public virtual IList<Dokument> Dokumente {
                get { return _dokumente; }
                set { _dokumente = value; }
            }
        }          

    My Code for Linking them together: (In service class DokumenteBS)

            

    public static bool AddBauteile(Guid id, List<Guid> selectedIds) {             using (var context = MyTgaDbContext.Create()) {                 var dokument = context.Dokumente.SingleOrDefault(b => b.ID == id);                 if (dokument == nullreturn false;                 foreach (var selectedId in selectedIds) {                     var bauteil = context.Bauteile.FirstOrDefault(d => d.ID == selectedId);                     if (bauteil != null) {                         dokument.Bauteile.Add(bauteil);                         bauteil.Dokumente.Add(dokument);                         context.SaveChanges();                     }                 }                 return true;             }         }

    Here everything is working fine. But when I move the context.SaveChanges() Call out of the loop to the End of the Method,

    I get the Multiplicity constraint violated error (Of course only if I link more than one at a time)

        

    Is my model wrong?

    nice greetings from Germany,

    Markus

    Friday, February 10, 2012 11:15 AM

Answers

  • Hi Markus,

    Thanks for your feedback!

    Yes, you can keep the self reference. But the code in your post :

    if (bauteil != null) {
                            dokument.Bauteile.Add(bauteil);
                            bauteil.Dokumente.Add(dokument);
                            context.SaveChanges();
                        }

    it is a cycle for the two tables. Just commend //bauteil.Dokumente.Add(dokument);

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Data.Entity;
    
    namespace Many
    {
        class Program
        {
            static void Main(string[] args)
            {
                using (var db= new MyContext())
                {
                    var dokument = db.Dokuments.FirstOrDefault();
                    foreach (var item in db.Bauteils.ToList())
                    {
                        dokument.Bauteile.Add(item);
                    }
                    db.SaveChanges();
                }
            }
        }
        public class Bauteil {
             //Keys
             public Guid ID { get; set; }
             public virtual IList<Bauteil> Bauteile
             {
                 get;
                 set;
             }
             public virtual IList<Dokument> Dokumente {
                 get;
                 set;
             }
         }           
        public class Dokument {
             //Keys
             public Guid ID { get; set; }
            public virtual IList<Bauteil> Bauteile {
                get;
                set;
             }
             public virtual IList<Dokument> Dokumente {
                 get;
                 set;
             }
         }
        public class MyContext:DbContext
        {
            public DbSet<Bauteil> Bauteils { get; set; }
            public DbSet<Dokument> Dokuments { get; set; }
        }     
    }
    
    Have a nice day.

    Alan Chen[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Tuesday, February 14, 2012 8:30 AM
    Moderator

All replies

  • Hi Markus,

    Welcome!

    According to your description, the relationship between Bauteile and Dokumente is many to many, right? Please change your model as follows:

    public class Bauteil : ElementBase, IAdresse {
             //Keys
             public Guid ID { get; set; }
            .....
             public virtual IList<Dokument> Dokumente {
                 get { return _dokumente; }
                 set { _dokumente = value; }
             }
         }           
    
        public class Dokument: ElementBase, IAdresse {
             //Keys
             public Guid ID { get; set; }
     
            .....
     
            public virtual IList<Bauteil> Bauteile {
                 get { return _bauteile; }
                 set { _bauteile = value; }
             }
         }           
    
    
    The Save code as follows:

    if (bauteil != null) { dokument.Bauteile.Add(bauteil); context.SaveChanges();// you can move it out of the loop

    }

    Have a nice day.

    Alan Chen[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Monday, February 13, 2012 7:15 AM
    Moderator
  • Hello Alean,

    thanks for your quick reply!!!

    But I still need a many to many relationsshipt from Bauteile to Bauteile and Dokumente to Dokumente. Not only from Bauteile to Dokumente... It should be like Bauteile having children Bauteile to build groups of Bauteile... Same for Dokumente.

    Do you have any suggestions for me?

    Kind regards, Markus

    Monday, February 13, 2012 8:39 AM
  • Hi Markus,

    Thanks for your feedback!

    Yes, you can keep the self reference. But the code in your post :

    if (bauteil != null) {
                            dokument.Bauteile.Add(bauteil);
                            bauteil.Dokumente.Add(dokument);
                            context.SaveChanges();
                        }

    it is a cycle for the two tables. Just commend //bauteil.Dokumente.Add(dokument);

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Data.Entity;
    
    namespace Many
    {
        class Program
        {
            static void Main(string[] args)
            {
                using (var db= new MyContext())
                {
                    var dokument = db.Dokuments.FirstOrDefault();
                    foreach (var item in db.Bauteils.ToList())
                    {
                        dokument.Bauteile.Add(item);
                    }
                    db.SaveChanges();
                }
            }
        }
        public class Bauteil {
             //Keys
             public Guid ID { get; set; }
             public virtual IList<Bauteil> Bauteile
             {
                 get;
                 set;
             }
             public virtual IList<Dokument> Dokumente {
                 get;
                 set;
             }
         }           
        public class Dokument {
             //Keys
             public Guid ID { get; set; }
            public virtual IList<Bauteil> Bauteile {
                get;
                set;
             }
             public virtual IList<Dokument> Dokumente {
                 get;
                 set;
             }
         }
        public class MyContext:DbContext
        {
            public DbSet<Bauteil> Bauteils { get; set; }
            public DbSet<Dokument> Dokuments { get; set; }
        }     
    }
    
    Have a nice day.

    Alan Chen[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Tuesday, February 14, 2012 8:30 AM
    Moderator
  • Hi Alan,

    thanks again. I have tried this yesterday, but then the Association is build up only in one directon. But I need it to see it from both sides.

    In the "Old days" of ADO I would have created a Link Table, write in one Association Record and then query it with a union from "both sides" to see all the Assiciations from both, Document and Bauteil and the other way around... But now with EF I'm a litte lost for this special situation... (Everything else works just great, especially the migration tools are perfect for me!!!!!)

    Nice greetings from germany,

    Markus

    Tuesday, February 14, 2012 9:06 AM
  • Hi Markus,

    The database diagram is :

    Many to Many relationship is two direction, there are navigation's properties for each entity. I'm not very sure about your requirement now, thanks for understanding.

    Have a nice day.


    Alan Chen[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Tuesday, February 14, 2012 9:15 AM
    Moderator
  • Hello Alan,

    Sorry, I must have missed something yesterday. It is working fine.

    Thanks a lot for your time and digging into my problem that deep and also for your detailed answers!!!!

    Kind regards,

    Markus

    Tuesday, February 14, 2012 9:41 AM
  • Hi Markus,

    You are welcome! I'm glad to help!

    Have a nice day.


    Alan Chen[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Wednesday, February 15, 2012 1:29 AM
    Moderator