Compartilhar via


Estados e controle de alterações de objeto

Objetos LINQ to SQL sempre participam de algum estado. Por exemplo, quando LINQ to SQL cria um novo objeto, o objeto está no Unchanged estado. Um novo objeto que você mesmo cria é desconhecido para o DataContext e está no estado Untracked. Após a execução bem-sucedida de SubmitChanges, todos os objetos conhecidos por LINQ to SQL estão no estado Unchanged. (A única exceção é representada por aqueles que foram excluídos com êxito do banco de dados, que estão no Deleted estado e inutilizáveis nessa DataContext instância.)

Estados de objeto

A tabela a seguir lista os estados possíveis para objetos LINQ to SQL.

Estado Descrição
Untracked Um objeto não rastreado pelo LINQ to SQL. Os exemplos incluem o seguinte:

- Um objeto não consultado por meio da corrente DataContext (como um objeto recém-criado).
- Um objeto criado por meio da desserialização
- Um objeto consultado com DataContext diferente.
Unchanged Um objeto recuperado usando o atual DataContext e sem que se saiba se foi modificado desde que foi criado.
PossiblyModified Um objeto que está anexado a um DataContext. Para mais informações, consulte Recuperação de Dados e Operações CUD em Aplicações N-Tier (LINQ to SQL).
ToBeInserted Um objeto não recuperado usando DataContextatual. Isso faz com que um base de dados INSERT durante SubmitChanges.
ToBeUpdated Um objeto conhecido por ter sido modificado desde que foi recuperado. Isso faz com que um base de dados UPDATE durante SubmitChanges.
ToBeDeleted Um objeto marcado para exclusão, causando um base de dados DELETE durante SubmitChanges.
Deleted Um objeto que foi excluído no banco de dados. Esse estado é final e não permite transições adicionais.

Inserindo objetos

Você pode solicitar Inserts explicitamente usando InsertOnSubmit. Como alternativa, LINQ to SQL pode inferir Inserts localizando objetos conectados a um dos objetos conhecidos que devem ser atualizados. Por exemplo, se você adicionar um Untracked objeto a um EntitySet<TEntity> ou definir um EntityRef<TEntity> para um Untracked objeto, tornará o Untracked objeto acessível por meio de objetos rastreados no grafo. Durante o processamento SubmitChanges, LINQ to SQL percorre os objetos rastreados e descobre todos os objetos persistentes acessíveis que não são rastreados. Esses objetos são candidatos à inserção no banco de dados.

Para classes em uma hierarquia de herança, InsertOnSubmit(o) também define o valor do membro designado como discriminatório para corresponder ao tipo do objeto o. No caso de um tipo que corresponda ao valor discriminatório padrão, essa ação faz com que o valor discriminatório seja substituído com o valor padrão. Para obter mais informações, consulte Suporte à Herança.

Importante

Um objeto adicionado a um Table não está no cache de identidade. O cache de identidade reflete apenas o que é recuperado do banco de dados. Após uma chamada para InsertOnSubmit, a entidade adicionada não aparece em consultas no banco de dados até que SubmitChanges seja concluído com êxito.

Excluindo objetos

Você marca um objeto acompanhado o para exclusão chamando DeleteOnSubmit() no Table<TEntity>apropriado. LINQ to SQL considera a remoção de um objeto de uma EntitySet<TEntity> operação de atualização e o valor de chave estrangeira correspondente é definido como nulo. O destino da operação (o) não é excluído de sua tabela. Por exemplo, cust.Orders.DeleteOnSubmit(ord) indica uma atualização em que a relação entre cust e ord é cortada definindo a chave ord.CustomerID estrangeira como nula. Ele não causa a exclusão da linha correspondente a ord.

O LINQ to SQL executa o seguinte processamento quando um objeto é excluído (DeleteOnSubmit) de sua tabela:

  • Quando SubmitChanges é chamada, uma DELETE operação é executada para esse objeto.

  • Remoção não é propagada a objetos relacionados independentemente se eles são carregados. Especificamente, os objetos relacionados não são carregados para atualizar a propriedade de relação.

  • Após a execução bem-sucedida de SubmitChanges, os objetos são definidos no estado Deleted. Como resultado, você não pode usar o objeto ou o seu id nele DataContext. O cache interno mantido por uma DataContext instância não elimina objetos recuperados ou adicionados como novos, mesmo após os objetos terem sido excluídos no banco de dados.

Você pode chamar DeleteOnSubmit apenas em um objeto rastreado pelo DataContext. Para um Untracked objeto, você deve chamar Attach antes de chamar DeleteOnSubmit. Chamar DeleteOnSubmit em um objeto Untracked gera uma exceção.

Observação

A remoção de um objeto de uma tabela instrui o LINQ to SQL a gerar um comando SQL DELETE correspondente no momento da execução de SubmitChanges. Essa ação não remove o objeto do cache nem propaga a exclusão para objetos relacionados.

Para recuperar o id objeto excluído, use uma nova DataContext instância. Para limpeza de objetos relacionados, você pode usar o recurso de exclusão em cascata do banco de dados ou excluir manualmente os objetos relacionados.

Os objetos relacionados não precisam ser excluídos em nenhuma ordem especial (diferentemente do banco de dados).

Atualizando objetos

Você pode detectar Updates observando notificações de alterações. As notificações são fornecidas com o evento de PropertyChanging em definidores de propriedade. Quando LINQ to SQL é notificado da primeira alteração em um objeto, ele cria uma cópia do objeto e considera o objeto um candidato para gerar uma instrução Update .

Para objetos que não implementam INotifyPropertyChanging, LINQ to SQL mantém uma cópia dos valores que os objetos tinham quando foram materializados pela primeira vez. Quando você chama SubmitChangesLINQ para SQL compara os valores atuais e originais para decidir se o objeto foi alterado.

Para atualizações para relações, a referência de filho ao pai (ou seja, a referência que corresponde à chave estrangeira) é considerada a autoridade. A referência na direção inversa (ou seja, de pai para filho) é opcional. Classes de relação (EntitySet<TEntity> e EntityRef<TEntity>) garantem que as referências bidirecionais sejam consistentes para relações um-para-muitos e um-para-um. Se o modelo de objeto não usar EntitySet<TEntity> ou EntityRef<TEntity> e se a referência inversa estiver presente, será sua responsabilidade mantê-la consistente com a referência direta quando o relacionamento for atualizado.

Se você atualizar a referência ambos necessário e a chave estrangeira correspondente, você deve certificar-se que concordam. Uma exceção de InvalidOperationException é lançada se os dois não são sincronizados momento em que você chamar SubmitChanges. Embora mudanças nos valores das chaves estrangeiras sejam suficientes para provocar uma atualização da linha subjacente, você deve alterar a referência para manter a conectividade do gráfico de objetos e a consistência bidirecional dos relacionamentos.

Consulte também