Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Save a relation with between two entities an N-N association

I've a Entity Framework 4.0, with poco object. the edmx model file is generated from the database.

This datacontext is accessed through WCF service, it's only mean that I receive some objects and I need to attach them to the current datacontext(or reload them with the key correspondance).

Everything seems to work fine, except for one case:

I've a N-N relationship between two table, so I've an association table, without any field other than ID of two tables: Database model

LINQ transform this into the following schema, this seems to be right. LINQ Data model

When I retrieve data, there is no problem, data I've inserted myself in the Right_group are correctly transformed into "new object in my collection of Rights/Groups".

But if I try to modify something and save, it doesn't work

 public void SaveRights(Group group, List<Rights> rights){
     //here, group and rights are objects attached to the database
     group.Rights.Clear();
     group.Rights.AddRange(rights);
     _dataContext.SaveChanges();
 }

So my question is: How to save this "relationship" of two objects ? Thank you!

like image 694
J4N Avatar asked Feb 17 '11 06:02

J4N


1 Answers

If you want to avoid loading the objects from the database first you can do it like this(Code taken from one of my aplications so you will have to adapt it):

    public void AddAndRemovePersons(int id, int[] toAdd, int[] toDelete)
    {
        var mailList = new MailList { ID = id, ContactInformations = new List<ContactInformation>() };        
        this.db.MailLists.Attach(mailList);

        foreach (var item in toAdd)
        {
            var ci = new ContactInformation { ID = item };
            this.db.ContactInformations.Attach(ci);
            this.db.ObjectStateManager.ChangeRelationshipState(mailList, ci, ml => ml.ContactInformations, System.Data.EntityState.Added);
        }

        foreach (var item in toDelete)
        {

            var ci = new ContactInformation { ID = item };
            this.db.ContactInformations.Attach(ci);
            this.db.ObjectStateManager.ChangeRelationshipState(mailList, ci, ml => ml.ContactInformations, System.Data.EntityState.Deleted);
        }
    }

I found deleting the relationship as hard as creating it so I left that code in there. One thing about this solution is that both the maillist and the contacts exist prior to this function being run. I attach them to make the state manager track them.

If you are adding new objects that you also want to save you would use the

this.db.MailLists.AddObject(you new item here)

I hope that helps!

like image 183
Mikael Eliasson Avatar answered Oct 21 '22 20:10

Mikael Eliasson