none
Problem by Add/Remove entities Many to Many RRS feed

  • Question

  • Hello;

    I'm working in a project where I use the Entity Framework 4.1 and I'm in trouble with an entity many to many.

    I have a CRUD of questions and those questions can have many answer items, so, when I'm editing a question I remove all of the answer items connected to question and I add new items.

    I'm doing on this way:

    PerguntaBO bo = new PerguntaBO();
    ItemRespostaBO boItemResposta = new ItemRespostaBO();
    
    if(UtilBO.CodigoPergunta > 0)
        pergunta = bo.GetById(UtilBO.CodigoPergunta); //Find the question when it exist
    
    foreach (ITEM_RESPOSTA item in pergunta.ITEM_RESPOSTA.ToList())
    {
        pergunta.ITEM_RESPOSTA.Remove(item); //Remove the answer items of the question
    }
    
    foreach (DataGridViewRow row in dgvItensResposta.Rows)
    {
        itemResposta = new ITEM_RESPOSTA();
        
        if (row.Cells[1].Value != null && row.Cells[2].Value != null)
        {
            if (row.Cells[0].Value != null)
                itemResposta = boItemResposta.GetById(int.Parse(row.Cells[0].Value.ToString()));
            ...
            pergunta.ITEM_RESPOSTA.Add(itemResposta); //Add new answer item or existing answer item in the question
        }
    }
    
    if (bo.SalvarPergunta(pergunta, UtilBO.CodigoQuestionario, out msg)) //Save question
    {
         ...
    }
    
    
    public class PerguntaBO : ObjectBO<PERGUNTA>
    {
         public bool SalvarPergunta(PERGUNTA pergunta, int cdQuestionario, out string msg)
         {
              model.Entry(pergunta).State = System.Data.EntityState.Modified;
              model.SaveChanges(); //save question
         }
    }

    At the moment I execute the command model.Entry(pergunta).State = System.Data.EntityState.Modified I receive this erro message:

    The relationship between the two objects cannot be defined because they are attached to different ObjectContext objects.

    Someone knows why this happen? I can to remove all items and save the entity PERGUNTA with no errors, but always at the moment when I add new items or existing items in the questions I receive this error! When the answer item not exists in the database I don't receive this error because the method boItemResposta.GetById  is not executed.

    Somebody knows what I can do to solve this problem?

    Thanks!

    Deise Vicentin
    "Eu não procuro saber as respostas, procuro compreender as perguntas." Confúcio



    • Edited by Deise Vicentin Wednesday, July 18, 2012 2:39 PM Translate thread
    Tuesday, July 17, 2012 1:43 AM

Answers

  • Hi;

    I solved my problem.

    I changed the method SalvarPergunta():

    //I add the items in a List in Code Behind of the page
    foreach (DataGridViewRow row in dgvItensResposta.Rows)
    {
        itemResposta = new ITEM_RESPOSTA();
    
        if (row.Cells[1].Value != null && row.Cells[2].Value != null)
        {
            if (row.Cells[0].Value != null)
                itemResposta.ITRE_ID_ITEM_RESPOSTA = int.Parse(row.Cells[0].Value.ToString());
    
            itemResposta.ITRE_DS_ITEM_RESPOSTA = row.Cells[1].Value.ToString();
            itemResposta.ITRE_NR_ORDEM = int.Parse(row.Cells[2].Value.ToString());
    
            itensResposta.Add(itemResposta);
                                                                    
        }
    }
    
    //The method SalvarPergunta receive that List
    public bool SalvarPergunta(PERGUNTA pergunta, int cdQuestionario, out string msg, List<ITEM_RESPOSTA> itensResposta)
    {
        bool _flag = false;
        msg = "";
    
        try
        {
            QuestionarioBO boQuestionario = new QuestionarioBO();
            QUESTIONARIO questionario = (from q in model.QUESTIONARIO where q.QUES_ID_QUESTIONARIO == cdQuestionario select q).FirstOrDefault();
    
            if (questionario != null)
            {
                if (pergunta.PERG_ID_PERGUNTA == 0)
                {   
                    model.PERGUNTA.Add(pergunta);
                    pergunta.QUESTIONARIO.Add(questionario);
                    model.SaveChanges();
                            
                    msg = "Success";
                    _flag = true;                        
                }
                else
                {
                    if (pergunta.PERG_CD_TIPO_PERGUNTA == 2) //If Type question is 2 = Closed Question
                    {
                        foreach (ITEM_RESPOSTA item in pergunta.ITEM_RESPOSTA.ToList()) //Remove old items of question
                        {
                            pergunta.ITEM_RESPOSTA.Remove(item);
                        }
    
                        _flag = SalvarPergunta(pergunta); //Save question with no items
    
                        ITEM_RESPOSTA itemResposta = new ITEM_RESPOSTA();
    
                        //Add new Items to question
                        foreach (ITEM_RESPOSTA item in itensResposta)
                        {
                            itemResposta = new ITEM_RESPOSTA();
    
                            if (item.ITRE_ID_ITEM_RESPOSTA > 0)
                                itemResposta = (from ir in model.ITEM_RESPOSTA where ir.ITRE_ID_ITEM_RESPOSTA == item.ITRE_ID_ITEM_RESPOSTA select ir).FirstOrDefault();
                            else
                                itemResposta = item;
    
                            pergunta.ITEM_RESPOSTA.Add(itemResposta);
                                        
                        }
                    }
    
                    _flag = SalvarPergunta(pergunta); //Save question with new items
     
                    if (_flag)
                        msg = "Success!";
                }
            }
        }
        catch (Exception)
        {
            msg = "Error!";
            //throw;
        }
    
        return _flag;
    }
    
    private bool SalvarPergunta(PERGUNTA pergunta)
    {
        bool _flag = false;
    
        try
        {
            model.Entry(pergunta).State = System.Data.EntityState.Modified;
            model.SaveChanges();
            _flag = true;
        }
        catch (Exception)
        {                
            throw;
        }
    
        return _flag;
    }

    Now, my project is working very well.

    Thanks and Best Regards!


    Deise Vicentin
    "Eu não procuro saber as respostas, procuro compreender as perguntas." Confúcio

    Friday, July 20, 2012 2:19 AM

All replies

  • Hi Deise,

    Welcome to the MSDN forum.

    Since this queue is an English forum, please translate your post to English to help more members join your thread.

    Have a nice day.  


    Alexander Sun [MSFT]
    MSDN Community Support | Feedback to us

    Wednesday, July 18, 2012 6:03 AM
  • Hi Deise,

    Welcome to the MSDN forum.

    Since this queue is an English forum, please translate your post to English to help more members join your thread.

    Have a nice day.  


    Alexander Sun [MSFT]
    MSDN Community Support | Feedback to us

    Hi Alexander;

    I did confusion with the language of this forum, I didn't choose portuguese...but now I translated the thread.
    Thanks for tell me.


    Deise Vicentin
    "Eu não procuro saber as respostas, procuro compreender as perguntas." Confúcio

    Wednesday, July 18, 2012 1:00 PM
  • Hi Deise,

    Could you please let me know if ITEM_RESPOSTA is a navigation property? 

    Also, what is the "mode" in SalvarPergunta(...) method? Another context?

    In addition, If you have any variable which is an entity type, and it is assigned to a different context, then you'd experience this problem. I believe you get this error only when you truly have two contexts and try to join them together (pergunta and model? I guess).

    I hope this helps.


    Alexander Sun [MSFT]
    MSDN Community Support | Feedback to us

    Thursday, July 19, 2012 3:01 PM
  • Hi Deise,

    Could you please let me know if ITEM_RESPOSTA is a navigation property? 

    Also, what is the "mode" in SalvarPergunta(...) method? Another context?

    In addition, If you have any variable which is an entity type, and it is assigned to a different context, then you'd experience this problem. I believe you get this error only when you truly have two contexts and try to join them together (pergunta and model? I guess).

    I hope this helps.


    Alexander Sun [MSFT]
    MSDN Community Support | Feedback to us

    Hi Alexander;

    I think you're right.

    I have a class (ObjectBO) where I have the instance of model and the another classes are using the same model extends ObjectBO, for example:

    public class ObjectBO<T>
    {
       Model model;
    
       //I have here the inicialization of model
    }
    
    public class PerguntaBO : ObjectBO<PERGUNTA>
    {
    
    }
    
    public class ItemPerguntaBO : ObjectBO<ITEM_PERGUNTA>
    {
    
    }

    When I call the method boItemResposta.GetById(id) I use the model was instantiated by ItemRespostaBO.

    In my database I have the entity PERGUNTA, ITEM_RESPOSTA and PERGUNTA_ITEM_RESPOSTA. The last one is the entity many to many. In the project I just can access the many to many entity using pergunta.ITEM_RESPOSTA or itemResposta.PERGUNTA.

    In SalvarPergunta() I've like that:

    if(pergunta.PERG_ID_PERGUNTA == 0)
        model.PERGUNTA.Add(pergunta);
    else
        model.Entry(pergunta).State = EntityState.Modified;
    
    model.SaveChanges();

    Thank for your help!


    Deise Vicentin
    "Eu não procuro saber as respostas, procuro compreender as perguntas." Confúcio

    Thursday, July 19, 2012 3:17 PM
  • Hi;

    I solved my problem.

    I changed the method SalvarPergunta():

    //I add the items in a List in Code Behind of the page
    foreach (DataGridViewRow row in dgvItensResposta.Rows)
    {
        itemResposta = new ITEM_RESPOSTA();
    
        if (row.Cells[1].Value != null && row.Cells[2].Value != null)
        {
            if (row.Cells[0].Value != null)
                itemResposta.ITRE_ID_ITEM_RESPOSTA = int.Parse(row.Cells[0].Value.ToString());
    
            itemResposta.ITRE_DS_ITEM_RESPOSTA = row.Cells[1].Value.ToString();
            itemResposta.ITRE_NR_ORDEM = int.Parse(row.Cells[2].Value.ToString());
    
            itensResposta.Add(itemResposta);
                                                                    
        }
    }
    
    //The method SalvarPergunta receive that List
    public bool SalvarPergunta(PERGUNTA pergunta, int cdQuestionario, out string msg, List<ITEM_RESPOSTA> itensResposta)
    {
        bool _flag = false;
        msg = "";
    
        try
        {
            QuestionarioBO boQuestionario = new QuestionarioBO();
            QUESTIONARIO questionario = (from q in model.QUESTIONARIO where q.QUES_ID_QUESTIONARIO == cdQuestionario select q).FirstOrDefault();
    
            if (questionario != null)
            {
                if (pergunta.PERG_ID_PERGUNTA == 0)
                {   
                    model.PERGUNTA.Add(pergunta);
                    pergunta.QUESTIONARIO.Add(questionario);
                    model.SaveChanges();
                            
                    msg = "Success";
                    _flag = true;                        
                }
                else
                {
                    if (pergunta.PERG_CD_TIPO_PERGUNTA == 2) //If Type question is 2 = Closed Question
                    {
                        foreach (ITEM_RESPOSTA item in pergunta.ITEM_RESPOSTA.ToList()) //Remove old items of question
                        {
                            pergunta.ITEM_RESPOSTA.Remove(item);
                        }
    
                        _flag = SalvarPergunta(pergunta); //Save question with no items
    
                        ITEM_RESPOSTA itemResposta = new ITEM_RESPOSTA();
    
                        //Add new Items to question
                        foreach (ITEM_RESPOSTA item in itensResposta)
                        {
                            itemResposta = new ITEM_RESPOSTA();
    
                            if (item.ITRE_ID_ITEM_RESPOSTA > 0)
                                itemResposta = (from ir in model.ITEM_RESPOSTA where ir.ITRE_ID_ITEM_RESPOSTA == item.ITRE_ID_ITEM_RESPOSTA select ir).FirstOrDefault();
                            else
                                itemResposta = item;
    
                            pergunta.ITEM_RESPOSTA.Add(itemResposta);
                                        
                        }
                    }
    
                    _flag = SalvarPergunta(pergunta); //Save question with new items
     
                    if (_flag)
                        msg = "Success!";
                }
            }
        }
        catch (Exception)
        {
            msg = "Error!";
            //throw;
        }
    
        return _flag;
    }
    
    private bool SalvarPergunta(PERGUNTA pergunta)
    {
        bool _flag = false;
    
        try
        {
            model.Entry(pergunta).State = System.Data.EntityState.Modified;
            model.SaveChanges();
            _flag = true;
        }
        catch (Exception)
        {                
            throw;
        }
    
        return _flag;
    }

    Now, my project is working very well.

    Thanks and Best Regards!


    Deise Vicentin
    "Eu não procuro saber as respostas, procuro compreender as perguntas." Confúcio

    Friday, July 20, 2012 2:19 AM