Partilhar via


Estados do objeto e controle de alterações

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.

Condição Description
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 arquivo .DataContext
Unchanged Um objeto recuperado usando o atual DataContext e não conhecido por ter sido modificado desde que foi criado.
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 faz com que um banco de dados INSERT durante SubmitChangeso .
ToBeUpdated Um objeto conhecido por ter sido modificado desde que foi recuperado. Isso faz com que um banco de dados UPDATE durante SubmitChangeso .
ToBeDeleted Um objeto marcado para exclusão, causando um banco de dados DELETE durante SubmitChangeso .
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() também define o valor do membro designado como o discriminador para corresponder ao tipo do objetooo. 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 a 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é SubmitChanges que seja concluída com êxito.

Excluindo objetos

Você marca um objeto o rastreado para exclusão chamando DeleteOnSubmit(o) no arquivo Table<TEntity>. 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 um objeto rastreado DataContextpelo . Para um Untracked objeto, você deve chamar Attach antes de chamar DeleteOnSubmit. Chamar DeleteOnSubmit um Untracked objeto gera uma exceção.

Nota

A remoção de um objeto de uma tabela informa ao LINQ to SQL para 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 PropertyChanging evento 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 você chama SubmitChangeso , 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. Se o modelo de objeto não usar EntitySet<TEntity> ou EntityRef<TEntity>, e se a referência reversa estiver presente, é sua responsabilidade mantê-lo consistente com a referência de encaminhamento quando a relação for atualizada.

Se você atualizar a referência necessária e a chave estrangeira correspondente, você deve certificar-se de que eles concordam. 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.

Consulte também