none
Como alterar o Entity.State de uma collection. Entity Framework duplica registros em associação N:N RRS feed

  • Pergunta

  • Bom dia!

    Recentemente publiquei uma dúvida, onde o Entity Framework estava duplicando meus registros em relacionamentos 1:N. Como solução respondida pelo fórum, declarei meu objeto filho como virtual e também defini um atributo ObjetoID para atribuir o valor da FK. Feito isso, resolveu.

    Meu problema agora é que preciso passar uma lista de Advogados que estão associados a um processo. O problema é que ao adicionar advogados (previamente já cadastrados) em uma hashset no objeto processo, e enviar para o contexto e executar o método savechanges, o processo é salvo perfeitamente, porém, a tabela de advogados tem os registros existentes na lista de advogados, cadastrados novamente, tornando a tabela de advogados com dados redudantes.

    Em pesquisas percebi que há a possibilidade de alterar o Entity.State do objeto, mas não consigo fazer isso em relação a uma coleção. Gera a exceção: The entity type HashSet`1 is not part of the model for the current context.

    Alguém já passou por esse tipo de problema? Como posso adicionar um novo processo sem inserir advogados?

    Detalhe: estou trabalhando em um projeto em camadas, onde não manipulo o contexto na camada de apresentação. Uso um repositório para manipular o contexto.


    Thiago Tácito Siqueira

    terça-feira, 9 de setembro de 2014 14:26

Respostas

  • Boa noite!

    Como voce esta usando um repositorio o certo seria vc chamar o repositorio de advogados para cada advogado da coleção e passar se eh um novo ou update, usando a propriedade entity state, o mesmo deve esta na coleção do objeto processo para manter o relacionamento.

    context.Entry(entity).State = EntityState.Added;
    
    context.Entry(entity).State = EntityState.Modified; 

    Nao eh possível alterar o entity state em coleções.


    Att,
    Breno Queiroz
    Blog Breno Queiroz


    • Marcado como Resposta Thiago Tácito quarta-feira, 10 de setembro de 2014 13:19
    • Editado Breno Queiroz quinta-feira, 11 de setembro de 2014 18:31
    terça-feira, 9 de setembro de 2014 22:53
  • Bom dia!

    A solução adotada foi a seguinte:

    Primeiramente, ao adicionar advogados na lista de advogados em processo, eu adiciono de forma que eu busco o advogado no contexto a partir do id, ex: contexto.find(id).

    E, no momento de gravar processos, eu criei no repositório de processos um método específico que percorre minha coleção de advogados, e nesse momento eu consigo alterar o estado da entidade para Inalterado - Unchanged.

    foreach (Advogado adv in lista)
                {
                    base.GetContext().Entry(adv).State = EntityState.Unchanged;
                }
    Só depois de feito esse procedimento é que adiciono o processo ao contexto e salvo no banco de dados.


    Thiago Tácito Siqueira

    • Marcado como Resposta Thiago Tácito quarta-feira, 10 de setembro de 2014 13:27
    quarta-feira, 10 de setembro de 2014 13:27

Todas as Respostas

  • Thiago como eu lhe informei no outro post esse problema irá ocorrer, até disse para que você criasse suas tabelas como o exemplo pois assim você iria mapear a tabela de relacionamento. 

    Vou te passar outro exemplo para ver se resolve seu problema.

    public void IncluirExcluirPerfilUsuario(string usuario, string itensDisponiveis, string itensDoUsuario, string tipoAcao) { int codigoUser = Convert.ToInt32(usuario); using (SistemaLeilao_DB db = new SistemaLeilao_DB()) { var select = (from a in db.Users where a.UserId == codigoUser select a).FirstOrDefault(); if (select != null) { if (tipoAcao.Equals("Incluir")) { string[] array = itensDisponiveis.Split(',');

    // Aqui pra baixo faço a validação necessária para a não duplicação for (int i = 0; i < array.Length; i++) { var user = db.Users.Find(select.UserId); var profile = db.Profiles.Find(Convert.ToInt32(array[i])); if (user.Profiles != null) profile.Users.Add(user); else profile.Users = new Collection<Users> { user }; db.SaveChanges(); } } else { string[] array = itensDoUsuario.Split(',');

    // Aqui pra baixo faço a validação necessária para efetuar a exclusão correta for (int i = 0; i < array.Length; i++) { var user = db.Users.Find(select.UserId); var profile = db.Profiles.Find(Convert.ToInt32(array[i])); if (user.Profiles != null) profile.Users.Remove(user); db.SaveChanges(); } } } } }

    Sem falar que na sua tabela de relacionamento deve conter 3 PK's. 

    http://social.msdn.microsoft.com/Forums/pt-BR/716e5d2a-697a-4652-aa67-ef6e3b7de9f8/ef6-inserir-dados-existentes-na-tabela-roles-amarrando-com-um-novo-profile-na-tabela-de?forum=adoptpt

    Infelizmente eu não achei uma outra thread. 

    Abraço. 

    terça-feira, 9 de setembro de 2014 14:57
  • Boa noite!

    Como voce esta usando um repositorio o certo seria vc chamar o repositorio de advogados para cada advogado da coleção e passar se eh um novo ou update, usando a propriedade entity state, o mesmo deve esta na coleção do objeto processo para manter o relacionamento.

    context.Entry(entity).State = EntityState.Added;
    
    context.Entry(entity).State = EntityState.Modified; 

    Nao eh possível alterar o entity state em coleções.


    Att,
    Breno Queiroz
    Blog Breno Queiroz


    • Marcado como Resposta Thiago Tácito quarta-feira, 10 de setembro de 2014 13:19
    • Editado Breno Queiroz quinta-feira, 11 de setembro de 2014 18:31
    terça-feira, 9 de setembro de 2014 22:53
  • Bom dia!

    A solução adotada foi a seguinte:

    Primeiramente, ao adicionar advogados na lista de advogados em processo, eu adiciono de forma que eu busco o advogado no contexto a partir do id, ex: contexto.find(id).

    E, no momento de gravar processos, eu criei no repositório de processos um método específico que percorre minha coleção de advogados, e nesse momento eu consigo alterar o estado da entidade para Inalterado - Unchanged.

    foreach (Advogado adv in lista)
                {
                    base.GetContext().Entry(adv).State = EntityState.Unchanged;
                }
    Só depois de feito esse procedimento é que adiciono o processo ao contexto e salvo no banco de dados.


    Thiago Tácito Siqueira

    • Marcado como Resposta Thiago Tácito quarta-feira, 10 de setembro de 2014 13:27
    quarta-feira, 10 de setembro de 2014 13:27