Partilhar via


Estados do objeto e Change-Tracking

Os objetos LINQ to SQL sempre participam de algum estado. Por exemplo, quando o 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 Untracked estado. Após a execução bem-sucedida do SubmitChanges, todos os objetos conhecidos pelo LINQ to SQL estão no Unchanged estado. (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 do 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 através da corrente DataContext (como um objeto recém-criado).
- Um objeto criado através de desserialização
- Um objeto consultado através de um DataContext.
Unchanged Um objeto recuperado usando o atual DataContext e que não é conhecido por ter sido modificado desde a sua criação.
PossiblyModified Um objeto que está anexado a um DataContextarquivo . Para obter mais informações, consulte Recuperação de dados e operações CUD em aplicativos de N camadas (LINQ to SQL).
ToBeInserted Um objeto não recuperado usando o atual DataContext. Isso provoca um banco de dados INSERT durante o SubmitChanges.
ToBeUpdated Um objeto conhecido por ter sido modificado desde que foi recuperado. Isso provoca um banco de dados UPDATE durante o SubmitChanges.
ToBeDeleted Um objeto marcado para exclusão, causando um erro na base de dados DELETE durante SubmitChanges.
Deleted Um objeto que foi excluído no banco de dados. Este estado é final e não permite transições adicionais.

Inserindo objetos

Você pode solicitar Inserts explicitamente usando InsertOnSubmit. Como alternativa, o 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> a um Untracked objeto, tornará o Untracked objeto acessível por meio de objetos rastreados no gráfico. Durante o processamento SubmitChanges, o LINQ to SQL percorre os objetos rastreados e descobre quaisquer objetos persistentes alcançáveis que não são rastreados. Tais objetos são candidatos para 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 o discriminador para corresponder ao tipo do objeto o. No caso de um tipo correspondente ao valor do discriminador padrão, essa ação faz com que o valor do discriminador seja substituído pelo valor padrão. Para obter mais informações, consulte Suporte de 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 nas consultas à base de dados até que SubmitChanges seja concluído com êxito.

Excluindo objetos

Você marca um objeto o rastreado para eliminação chamando DeleteOnSubmit(o) na Table<TEntity> apropriada. LINQ to SQL considera a remoção de um objeto de uma EntitySet<TEntity> operação como uma atualização, e o valor da chave estrangeira correspondente é definido como null. 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 é chamado, uma DELETE operação é executada para esse objeto.

  • A remoção não é propagada para objetos relacionados, independentemente de eles serem carregados. Especificamente, os objetos relacionados não são carregados para atualizar a propriedade de relacionamento.

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

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

Observação

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

Para recuperar o id de um 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 (ao contrário do banco de dados).

Atualizando objetos

Você pode detetar Updates observando notificações de alterações. As notificações são fornecidas através do evento PropertyChanging em setters de propriedade. Quando o 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 Update instrução.

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

Para atualizações de relacionamentos, a referência do filho ao pai (ou seja, a referência correspondente à chave estrangeira) é considerada a autoridade. A referência no sentido inverso (isto é, de pai para filho) é opcional. As classes de relacionamento (EntitySet<TEntity> e EntityRef<TEntity>) garantem que as referências bidirecionais sejam consistentes para relacionamentos um-para-muitos e um-para-um. Caso o modelo de objeto não utilize EntitySet<TEntity> ou EntityRef<TEntity>, e se a referência reversa estiver presente, é sua responsabilidade mantê-la consistente com a referência direta quando a relação for atualizada.

Se atualizares tanto a referência necessária como a chave estrangeira correspondente, deves assegurar-te de que estão concordantes. Uma InvalidOperationException exceção será lançada se os dois não estiverem sincronizados no momento em que você chamar SubmitChanges. Embora as alterações no valor da chave estrangeira sejam suficientes para afetar uma atualização da linha subjacente, você deve alterar a referência para manter a conectividade do gráfico de objeto e a consistência bidirecional das relações.

Ver também