Solucionado (ver solução)
Solucionado
(ver solução)
3
respostas

Exceção não tratada em chave composta

Estou fazendo um projeto que utiliza exatamente este conceito de chave composta:

Possuo uma classe Cliente, uma classe Telefone. Ao tentar inserir no contexto, recebo a seguinte exceção:

System.InvalidOperationException: 'The instance of entity type 'UsuarioTelefone' cannot be tracked because another instance of this type with the same key is already being tracked. When adding new entities, for most key types a unique temporary key value will be created if no key is set (i.e. if the key property is assigned the default value for its type). If you are explicitly setting key values for new entities, ensure they do not collide with existing entities or temporary values generated for other new entities. When attaching existing entities, ensure that only one entity instance with a given key value is attached to the context.'

Pelo que pude constatar, os Id's de ambas as classes estão adicionadas com zero. Como os Id's são iguais, causou essa exceção.

Como posso resolver esta questão?

Desde já agradeço!

3 respostas

Olá, Rennan

Para termos uma ideia melhor do que está acontecendo, você pode postar aqui o código do seu modelo (Cliente, Telefone, etc.), para darmos uma olhada? Obrigado!

solução!

Marcelo,

Encontrei a causa do problema. O Entity cria um campo no banco com a convenção NomeDaTabelaId, enquanto eu havia criado com a convenção IdNomeDaTabela.

public class Usuario {
    public int Id { get ; set ; }
}

public class Telefone{
    public int Id { get ; set ; }
}

public class UsuarioTelefone{
    public Usuario Usuario { get ; set ; }
    public int IdUsuario { get ; set ; }
    public Telefone Telefone { get ; set ; }
    public int IdTelefone { get ; set ; }
}

Ao migrar para o banco, ele criou as colunas UsuarioId e TelefoneId e manteve as colunas de Id que eu criei. Sendo assim, houve o erro de chaves iguais. O problema foi resolvido ao renomear as proriedades na classe UsuarioTelefone.

public class UsuarioTelefone{
    public Usuario Usuario { get ; set ; }
    public int UsuarioId { get ; set ; }
    public Telefone Telefone { get ; set ; }
    public int TelefoneId { get ; set ; }
}

Obrigado pela disposição.

Att.

Excelente, Rennan! Essas convenções às vezes nos confundem :-)

Mas se você tiver que/quiser forçar os nomes da chave primária, basta utilizar sobre o nome da propriedade o atributo [Key]:

[Key]
public class Usuario {
    public int IdUsoONomeQueQuiserEDai { get ; set ; }
}