Pergunta

http://geekswithblogs.net/michelotti/archive/2007 /12/17/117791.aspx

Eu estou usando ASP.NET com C # e tentando usar o LINQ to SQL para atualizar um contexto de dados como exibido no blog ligada acima. Eu criei o campo timestamp na tabela apenas como indicado e estou usando o seguinte método:

private void updateRecord(TableName updatedRecord)
{
 context db = new context();
 db.TableName.Attach(updatedRecord,true);
 db.SubmitChanges();
}

A minha pergunta é, você deveria atribuir o campo timeStamp a qualquer coisa na sua updatedRecord antes de tentar chamar o método Anexar no seu contexto de dados?

Quando eu executar esse código eu recebo a seguinte exceção: System.Data.Linq.ChangeConflictException: Row not found or changed. eu atualizar todos os campos, incluindo a chave primária do registro que eu estou atualizando antes de passar o objeto para este método de actualização. Durante a depuração do atributo timestamp da mostra de objectos como nulo. Eu não tenho certeza se é suposto ser assim ou não.

Cada livro e recurso que tenho diz que esta é a maneira de fazê-lo, mas nenhum deles entrar em grandes detalhes sobre esse atributo timestamp.

Eu sei que isso é rápido e fácil, então se alguém souber, por favor me avise.

Foi útil?

Solução

Se você tem uma coluna timestamp, em seguida, para atualizar um registro (a partir de um objeto de baunilha): sim, eu esperaria ter que atribuí-lo. Caso contrário, você perde a capacidade de usar o timestamp para verificação de simultaneidade otimista.

A idéia é que você toma uma cópia do timestamp quando você se apossar do seu objeto (desconectado), então quando você atualizar você pode usar esta coluna para verificar que ninguém editou a linha.

Existem dois cenários comuns:

1: se você está apenas realizando uma operação de curta duração, obter o registro do banco de dados em primeiro lugar - fazer suas alterações para o objeto e simplesmente SumbitChanges () [todos com os mesmos dados ao contexto]. O contexto de dados vai lidar com concorrência para você.

2: Se for desconectar o objeto (por exemplo, passando-a para um aplicativo cliente por um tempo), então usar algo como serialização (LINQ to SQL objetos suporte DataContractSerializer (opcionalmente, você precisa habilitá-lo)). Então serializar o objeto no servidor, passá-lo para o cliente - o cliente faz alterações em sua cópia e passa-lo de volta. O servidor desserializa-lo e usos Anexar () e SubmitChanges (). O registro na memória ainda deve ter o carimbo do tempo que tinha quando extraído da base de dados, para que possamos realizar concorrência otimista abrangendo todo o tempo o registro foi desconectado.

Outras dicas

Uma vez que você diz que criou o campo carimbo de tempo na tabela, gostaria de saber se, no caso em que esta coluna foi acrescentado mais tarde, as propriedades da coluna não pode ser definido corretamente. Você pode querer verificar as propriedades em sua coluna TimeStamp no designer DBML. Certifique-se de que:

AutoGenerated = true
Auto-Sync = Always
Time Stamp = True
Update Check = Never

O tipo de dados do servidor deve ser rowversion NOT NULL

Se não estiver definido para ser gerado automaticamente e sincronizado sempre, a versão de linha não serão devolvidos a partir da inserção desde que você não tenha alterado quando a inserção foi feito. Mesmo que este valor é gerado pelo banco de dados do DataContext precisa saber isso para que ele pode lidar com isso corretamente.

Além disso, agora que você tem uma coluna timestamp, UpdateCheck deve ser definido como Never para todas as outras colunas.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top