Eu tenho trabalhado com o Entity Framework 4 recentemente e estou um pouco confuso sobre quando usar ObjectSet.Attach e ObjectSet.AddObject .
Pelo meu entendimento:
- Use "Anexar" quando uma entidade já existir no sistema
- Use "AddObject" ao criar uma nova entidade
Então, se estou criando uma nova Pessoa , faço isso.
var ctx = new MyEntities();
var newPerson = new Person { Name = "Joe Bloggs" };
ctx.Persons.AddObject(newPerson);
ctx.SaveChanges();
Se estou modificando uma Pessoa existente , faço o seguinte:
var ctx = new MyEntities();
var existingPerson = ctx.Persons.SingleOrDefault(p => p.Name = "Joe Bloggs" };
existingPerson.Name = "Joe Briggs";
ctx.SaveChanges();
Lembre-se, este é um exemplo muito simples . Na realidade, estou usando Pure POCO (sem geração de código), padrão de repositório (não lida com ctx.Persons) e unidade de trabalho (não lida com ctx.SaveChanges). Mas "debaixo das cobertas", o acima é o que acontece na minha implementação.
Agora, minha pergunta - ainda estou para encontrar um cenário em que tive que usar o Attach .
O que estou perdendo aqui? Quando precisamos usar o Anexar?
EDITAR
Apenas para esclarecer, estou procurando exemplos de quando usar Anexar sobre AddObject (ou vice-versa).
EDIT 2
A resposta abaixo está correta (que eu aceitei), mas pensei em adicionar outro exemplo em que o Attach seria útil.
No meu exemplo acima, para modificar uma Pessoa existente , duas consultas estão realmente sendo executadas.
Um para recuperar a Pessoa (.SingleOrDefault) e outro para executar a UPDATE (.SaveChanges).
Se (por algum motivo), eu já sabia que "Joe Bloggs" existia no sistema, por que fazer uma consulta extra para obtê-lo primeiro? Eu poderia fazer isso:
var ctx = new MyEntities();
var existingPerson = new Person { Name = "Joe Bloggs" };
ctx.Persons.Attach(existingPerson);
ctx.SaveChanges();
Isso resultará em apenas uma instrução UPDATE sendo executada.
fonte
Respostas:
ObjectContext.AddObject e ObjectSet.AddObject :
Ométodo AddObject é para adicionar objetos recém-criados que não existem no banco de dados. A entidade receberá uma EntityKey temporária gerada automaticamentee seu EntityState será definido como Adicionado . Quando SaveChanges é chamado, fica claro para o EF que essa entidade precisa ser inserida no banco de dados.
ObjectContext.Attach e ObjectSet.Attach :
por outro lado, Attach é usado para entidades que já existem no banco de dados. Em vez de definir EntityState como Adicionado, Anexar resulta em umEntityState inalterado , o que significa que não foi alterado desde que foi anexado ao contexto. Os objetos que você está anexando são assumidos como existentes no banco de dados. Se você modificar os objetos depois que eles foram anexados, quando você chamar SaveChanges, o valor da EntityKey será usado para atualizar (ou excluir) a linha apropriada, localizando seu ID correspondente na tabela db.
Além disso, usando o método Attach, você pode definir relacionamentos entre entidades que já existem no ObjectContext, mas que possuemnão foi conectado automaticamente. Basicamente, o principal objetivo do Attach é conectar entidades que já estão anexadas ao ObjectContext e não sãonovas, portanto você não pode usar o Attach para anexar entidades cujo EntityState foi adicionado. Você precisa usar Add () neste caso.
Por exemplo, vamos supor que sua entidade Pessoa tenha uma propriedade de navegação denominada Endereços, que é uma coleção daentidade Endereço . Digamos que você tenha lido os dois Objetos a partir do contexto, mas eles não são relacionados um ao outro e você deseja fazê-lo:
fonte
Esta é uma resposta tardia, mas pode ajudar outras pessoas a encontrar isso.
Basicamente, uma entidade "desconectada" pode acontecer quando você manipula uma entidade fora do escopo "using".
Se você inserir outro escopo "using", a variável "e" será desconectada porque pertence ao escopo anterior "using" e, como o escopo anterior "using" é destruído, o "e" será desconectado.
É assim que eu entendo.
fonte
Esta é uma citação do Programming Entity Framework: DbContext
fonte
Que tal se referir apenas à chave primária em vez de anexar?
ou seja:
fonte