Compartilhar via


Identidade do objeto

Os objetos no runtime têm identidades exclusivas. Duas variáveis que se referem ao mesmo objeto realmente se referem à mesma instância do objeto. Devido a esse fato, as alterações feitas por meio de um caminho através de uma variável são imediatamente visíveis através da outra.

As linhas em uma tabela de banco de dados relacional não têm identidades exclusivas. Como cada linha tem uma chave primária exclusiva, nenhuma duas linhas compartilham o mesmo valor de chave. No entanto, esse fato restringe apenas o conteúdo da tabela de banco de dados.

Na realidade, os dados geralmente são trazidos para fora do banco de dados e para uma camada diferente, em que um aplicativo trabalha com ele. Esse é o modelo compatível com LINQ to SQL. Quando os dados são trazidos do banco de dados como linhas, você não tem nenhuma expectativa de que duas linhas que representam os mesmos dados correspondam realmente às mesmas instâncias de linha. Se você consultar um cliente específico duas vezes, obterá duas linhas de dados. Cada linha contém as mesmas informações.

Com objetos, você espera algo muito diferente. Espera-se que, se você pedir repetidamente ao DataContext as mesmas informações, ele de fato forneça a mesma instância de objeto. Você espera esse comportamento porque os objetos têm um significado especial para seu aplicativo e você espera que eles se comportem como objetos. Você os projetou como hierarquias ou grafos. Você espera recuperá-los como esta'n e não receber multidões de instâncias replicadas exatamente como você solicitou a mesma coisa mais de uma vez.

No LINQ to SQL, o DataContext gerencia a identidade do objeto. Sempre que você recupera uma nova linha do banco de dados, a linha é registrada em uma tabela de identidade por sua chave primária e um novo objeto é criado. Sempre que você recupera essa mesma linha, a instância de objeto original é retornada para o aplicativo. Dessa forma, o DataContext traduz o conceito de identidade como visto pelo banco de dados (ou seja, chaves primárias) no conceito de identidade visto pela linguagem (ou seja, instâncias). O aplicativo só vê o objeto no estado em que foi recuperado pela primeira vez. Os novos dados, se diferentes, são descartados. Para obter mais informações, consulte Recuperando objetos do Cache de Identidade.

O LINQ to SQL usa essa abordagem para gerenciar a integridade de objetos locais para dar suporte a atualizações otimistas. Como as únicas alterações que ocorrem depois que o objeto é criado pela primeira vez são aquelas feitas pelo aplicativo, a intenção do aplicativo é clara. Se as alterações por uma parte externo ocorreram em ínterim, são identificadas em SubmitChanges() é chamado.

Observação

Se o objeto solicitado pela consulta for facilmente identificável como um já recuperado, nenhuma consulta será executada. A tabela de identidade atua como um cache de todos os objetos recuperados anteriormente.

Exemplos

Exemplo de cache de objeto 1

Neste exemplo, se você executar a mesma consulta duas vezes, receberá uma referência ao mesmo objeto na memória todas as vezes.

Customer cust1 =
    (from cust in db.Customers
     where cust.CustomerID == "BONAP"
     select cust).First();

Customer cust2 =
    (from cust in db.Customers
     where cust.CustomerID == "BONAP"
     select cust).First();
Dim cust1 As Customer = _
    (From cust In db.Customers _
     Where cust.CustomerID = "BONAP" _
     Select cust).First()

Dim cust2 As Customer = _
    (From cust In db.Customers _
     Where cust.CustomerID = "BONAP" _
     Select cust).First()

Exemplo de cache de objeto 2

Neste exemplo, se você executar consultas diferentes que retornam a mesma linha do banco de dados, receberá uma referência ao mesmo objeto na memória todas as vezes.

Customer cust1 =
    (from cust in db.Customers
     where cust.CustomerID == "BONAP"
     select cust).First();

Customer cust2 =
    (from ord in db.Orders
     where ord.Customer.CustomerID == "BONAP"
     select ord).First().Customer;
Dim cust1 As Customer = _
    (From cust In db.Customers _
     Where cust.CustomerID = "BONAP" _
     Select cust).First()

Dim cust2 As Customer = _
    (From ord In db.Orders _
     Where ord.Customer.CustomerID = "BONAP" _
     Select ord).First().Customer

Consulte também