Como desanexar objetos no Entity Framework Code First?

Respostas:

156

Se você deseja desanexar o objeto existente, siga as recomendações de @ Slauma. Se você deseja carregar objetos sem acompanhar as alterações, use:

var data = context.MyEntities.AsNoTracking().Where(...).ToList();

Conforme mencionado no comentário, isso não desanexará completamente as entidades. Eles ainda estão anexados e o carregamento lento funciona, mas as entidades não são rastreadas. Isso deve ser usado, por exemplo, se você deseja carregar a entidade apenas para ler dados e não planeja modificá-los.

Ladislav Mrnka
fonte
3
@Ladislav: Este é realmente o significado do codificador Lol. Eu nunca usei e pensei sobre esse método, embora muitas vezes carregue listas de objetos e disponha o contexto de uma só vez, algo assim using(ctx){ return ctx....ToList(); }. Nesses casos, o uso AsNoTracking()faria muito sentido, porque eu economizaria preenchendo o contexto do objeto desnecessariamente. Eu acho que provavelmente teria um benefício de desempenho e consumo de memória, especialmente para listas grandes, certo?
Slauma
1
@ Sluma: Sim, tem benefício de desempenho. É por isso que esse método existe. O uso dessa abordagem na API ObjectContext é um pouco mais complicado.
Ladislav Mrnka
2
Isso desabilita o carregamento lento?
Shawn Mclean
3
Na verdade, isso não desativará o carregamento lento, apenas desativará o rastreamento de alterações e melhorará o desempenho = a entidade ainda está anexada. Eu o encontrei depois de responder a essa pergunta, então você deve marcar a resposta de @ Slauma como uma resposta válida.
Ladislav Mrnka
1
É isso que eu quero. Desejo carregamento lento e a capacidade de modificar apenas uma entidade desanexada.
perfil completo de Shawn Mclean
255

Esta é uma opção:

dbContext.Entry(entity).State = EntityState.Detached;
Slauma
fonte
3
Posso fazer isso ao recuperar objetos que retornam um IQueryable?
Shawn Mclean
1
@Lol coder: não sei se entendi direito, mas entitydeve ser um objeto materializado de um tipo que faça parte de suas classes de modelo (Pessoa, Cliente, Pedido, etc.). Você não pode passar diretamente um IQueryable <T> para dbContext.Entry(...). Essa é a pergunta que você quis dizer?
Slauma
9
@EladBenda: Depende. Se você deseja desanexar um objeto que já está anexado ao contexto, defina o estado para Detached. Se você deseja carregar entidades do banco de dados sem anexá-las ao contexto (sem rastreamento de alterações), use AsNoTracking.
Slauma
1
Encontrei um problema interessante com esse método. Mesmo que a entidade possa ser uma classe proxy, o carregamento lento não funcionará depois que você alterar o estado para Detached.
precisa saber é o seguinte
4
@kjbartel: esse é o comportamento esperado, uma vez que a entidade não tem vínculo com o contexto.
Ricardo Souza