none
Alterar Campo ID com Identify depois do Registro adicionado (Linq to SQL) RRS feed

  • Pergunta

  •  

    Olá minha duvida é a seguinte:

     

    - Eu tenho um sistema multiusuario sendo cada usuario tem seu ID de cadastro

    - Como este sistema existe um banco de dados local na maquina do usuario e outro no servidor entao é necessario um sincronismo periodico.

    - Neste mesmo sistema existe um Cadastro de Clientes, entao ai que vai a pergunta:

     

    Para nao haver conflito de ID no Cadastro de Clientes vindo de varios usuarios diferentes, eu quero que o campo ID do Cadastro de Clientes que é Identify, ou seja, auto increment. Entao eu quero adicionar o registro automatico entao o registro vai pegar o ID 51, daí eu quero reeditar o registro juntando o ID do Usuario formatado com 3 digitos exemplo:

     

    Id do Cliente: 51

    Id do Usuario: 5 (Formatado com 3 digitos ficaria: 005)

     

    dai eu queria editar o ID do Cliente para: 51005

     

    - So que eu nao to conseguindo fazer isso pois exite bloqueio no campo id para ediçao pois é Identidy

    - Ja ativei ON o SET IDENTITY_INSERT mas nao to conseguindo funcionar.

     

    Olha uma das tentativas minha q nao funciona:

     

    Obs: Eu crio um registro normal para pegar o ID do cliente, depois eu Crio outro com o ID alterado, gravo e apago o primeiro registro.

     

    Code Snippet

    Dim qAdiciona As New Cliente With { _

    .Nome = txtNome.Text, _

    .Telefone = txtTelefone.Text}

    dbConexao.Clientes.InsertOnSubmit(qAdiciona)

    dbConexao.SubmitChanges()

     

    '### INICIO - Duplica com ID alterada e apaga antigo ID

    dbConexao.ExecuteCommand("SET IDENTITY_INSERT Clientes ON")

    Dim qDuplicaId As New Cliente With { _

    .Id = CInt(qAdiciona.Id & Format(UserId, "000"))  'Altera o Id do cliente

    .Nome = txtNome.Text, _

    .Telefone = txtTelefone.Text}

    dbConexao.Clientes.InsertOnSubmit(qDuplicaId)

    dbConexao.Clientes.DeleteOnSubmit(qAdiciona) 'Apaga Registro antigo ID

    dbConexao.SubmitChanges()

    dbConexao.ExecuteCommand("SET IDENTITY_INSERT Clientes OFF")

    '### FIM - Duplica com ID alterada e apaga antigo ID

     

     

    Eu sei que não é legal colocar palavras como URGENTE em posts mas é pq eu preciso de uma soluçao para hoje ou ate amanha pq segunda eu tenho q entregar isso resolvido e estou aqui rancando os cabelos com isso. Para alguns pode parecer simples mas eu to apanhando aqui pois nunca fica algo parecido entao a soluçao pode ser simples mas qdo a gente ainda nao passou poriso pode parecer dificil.

     

    Se alguem quiser acrescentar alguma sugestao de como seria uma maneira pratica de sincronizar os banco de dados local do usuario e do servidor eu ficaria mais agradecido ainda.

     

    Obrigado desde já pela atençao oferecida e ficarei aqui aguardando ansioso por uma ajuda.

     

    VALEU GALERA!!!!

    sábado, 6 de dezembro de 2008 14:42

Respostas

  • Na hora,

     

    Saca só: como é feita a sincronização?

     

    A princípio sugiro o uso de replicação merge.

     

    Uma forma muito usada para campos Identity é definir ranges para cada um. Caso esteja usando replicação, vc pode definir um identity range. Dai cada assinate pega se range de valores e um valor nunca vai ser igual ao outro.

     

    Tanto para replicação ou não, vc pode definir manualmente o seed e o incremento da tabela cliente em cada banco de dados:

     

    Dê uma olhada para o caso de três bancos de dados

     

    Database 

    Seed

    Increment

    BD1

    1

    3

    BD2

    2

    3

    BD3

    3

    3

     

    Para definir o seed dê uma olhada neste exemplo:

     

    Code Snippet

    create table tbTeste(id int identity(1,1), nome char(1))

    GO

     

    insert into tbTeste (nome)values('A')

    insert into tbTeste (nome)values('B')

    insert into tbTeste (nome)values('C')

    GO

     

    select IDENT_CURRENT('tbTeste')

    GO

     

    dbcc checkident('tbteste', reseed, 0)--altera o seed que estava em 3 e fica 0

    GO

     

    select IDENT_CURRENT('tbTeste')

     

     

    A idéia é definir valores de increment e seed para cada BD de forma que esses valores nunca entrem em conflio.

     

    Abraçois

     

    domingo, 7 de dezembro de 2008 23:16
  • Como sincronismo posso sugerir que você faça uma replicação do tipo merge. Através da replicação, você pode definir um range a ser usado para cada banco de dados. Ex: quando o PC1 se conectar ao servidor central, ela pega o range de identity de 1 até 10000, já o pc 2 pega do 10001 até o 20000 e assim por diante. Não havendo assim conflitos.

     

    Dessa forma, você não precisaria setar manualmente cada identity. Bastava definir um range que será dado para cada computador. E todas as vezes que o range for complletado, o PC1 pega automaticamente um novo range de 10000 identitys.

     

    Caso não queira usar replicação, pode ficar setando manualmente o range de identitys para cada PC ( banco de dados no caso ).

     

     

    Segue um link que mostra como combinar ranges para várias qtds de databases:

     

    http://www.quest-pipelines.com/newsletter-v4/0903_F.htm

     

    Segue link falando sobre replicação:

     

    http://www.linhadecodigo.com.br/Artigo.aspx?id=1473

     

    Lembre-se, para o seu caso, aconselho o uso da topologia de replicação merge.

     

    Abraços

     

     

    segunda-feira, 8 de dezembro de 2008 12:29
  • Olá amigo,

     

    Marquei a seu post anterior como RESPOSTA, e agradeço muito pela sua atençao!

     

    So para acrescentar a parte de deixar a coisa automatizada poderia entao se fazer algo assim:

     

    Code Snippet

    Abaixo vai a StringSQL para criaçao do banco:

     

     

    "create table t1bTeste(id int identity(1,1), nome char(1))

    GO

     

    insert into tbTeste (nome)values('A')

    insert into tbTeste (nome)values('B')

    insert into tbTeste (nome)values('C')

    GO

     

    select IDENT_CURRENT('tbTeste')

    GO

     

    dbcc checkident('tbteste', reseed, " & UserID * 10000 & ") <--altera o seed que estava em 1 e fica ID do usuario multiplicado por 10000, ou seja, se o ID do usuario for 3 vai começar em 30.000 e assim para cada user

    GO

     

    select IDENT_CURRENT('tbTeste')"

     

     

     

    so  uma duvida, o Replication Mergue nao altera as propriedades Seed e Increment dos bancos para ficar igual a do servidor nao neh ?

     

     

    Abraçao meu amigo e muito obrigado mesmo pela ajuda.

     

    Cordialmente,

    Alexsandro Nunes

    Futura Informatica www.base1.com.br

    segunda-feira, 8 de dezembro de 2008 12:53

Todas as Respostas

  • Olá,

     

    Não entendi um monte de coisa:

     

    1 - Poque existe um banco de dados na máquina do usuário? Existe um banco de dados para cada usuário?

     

    2 - Campos IDENTITY não podem ser alterados

     

    "Para nao haver conflito de ID no Cadastro de Clientes vindo de varios usuarios diferentes, eu quero que o campo ID do Cadastro de Clientes que é Identify, ou seja, auto increment. Entao eu quero adicionar o registro automatico entao o registro vai pegar o ID 51, daí eu quero reeditar o registro juntando o ID do Usuario formatado com 3 digitos exemplo:"

     

    Acho que você deveria então definir a chave primária da tabela cliente como sendo outro tipo e não identity.

     

    A maior dúvida é: porque existem vários bancos de dados nas máquinas dos usuários?

    domingo, 7 de dezembro de 2008 16:02
  • Vamos lá meu amigo, deixa eu te explicar exatamente como funciona a coisa!

     

    Eu tenho um sistema de vendas, cada vendedor tem seu notebook e faz a venda diretamente no cliente, dai no final do dia ele irá sincronizar seu banco com a central. Mas ele nao vai so enviar seus dados mas tbem irá receber os dados atualizados do banco de dados central.

     

    Entao como existe varios vendedores, cada um sai no dia com o ultimo ID do cadastro de cliente sendo 50, entao se cada um dos vendedores cadastrar um cliente, todos ficará com o ID 51 desse novo cliente em seus notebooks.

    Qdo eles sincronizarem o primeiro q sincronizar o primeiro cliente dele do dia vai como 51, dai o segundo vendedor qdo sincronizar com a central nao vai poder usar o 51 pois ja existe. Entao eu bolei uma ideia de juntar o ID do cadastro do cliente com o ID do usuario para nao haver risco de duplicaçao.

     

    Eu faço tudo isso pq existe muitas tabelas com relacionamentos de chaves e todo o sistema se baseia no codigo do cliente pois qdo o vendedor efetua a venda no cliente o cliente ganha um ID e ele sempre passará a ser identificado por aquele numero apartir da venda efetuada pois qdo a venda for efetuada o vendedor ja vai deixar o pedido impresso com seu ID no pedido.

     

    Como os produtos so poderão ser cadastrados no banco central entao nao ha necessidade de se preocupar com ID duplicado mas os cadastros de clientes e vendas sim pois cada vendedor cadastrará o seu.

     

    A necessidade de um campo Identify é pq a cada cadastro eu preciso de um numero sequencial para cada novo cliente.

     

    Se tiver mais alguma duvida eu estaria aqui a disposiçao para responder, mas agradeço desde já pela atençao

     

    Brigadao

    domingo, 7 de dezembro de 2008 22:54
  • Na hora,

     

    Saca só: como é feita a sincronização?

     

    A princípio sugiro o uso de replicação merge.

     

    Uma forma muito usada para campos Identity é definir ranges para cada um. Caso esteja usando replicação, vc pode definir um identity range. Dai cada assinate pega se range de valores e um valor nunca vai ser igual ao outro.

     

    Tanto para replicação ou não, vc pode definir manualmente o seed e o incremento da tabela cliente em cada banco de dados:

     

    Dê uma olhada para o caso de três bancos de dados

     

    Database 

    Seed

    Increment

    BD1

    1

    3

    BD2

    2

    3

    BD3

    3

    3

     

    Para definir o seed dê uma olhada neste exemplo:

     

    Code Snippet

    create table tbTeste(id int identity(1,1), nome char(1))

    GO

     

    insert into tbTeste (nome)values('A')

    insert into tbTeste (nome)values('B')

    insert into tbTeste (nome)values('C')

    GO

     

    select IDENT_CURRENT('tbTeste')

    GO

     

    dbcc checkident('tbteste', reseed, 0)--altera o seed que estava em 3 e fica 0

    GO

     

    select IDENT_CURRENT('tbTeste')

     

     

    A idéia é definir valores de increment e seed para cada BD de forma que esses valores nunca entrem em conflio.

     

    Abraçois

     

    domingo, 7 de dezembro de 2008 23:16
  • Olá amigo,

     

    Achei interessante a sua ideia e gostaria de saber mais...

     

    Com 3 bancos eu entendi mais ou menos a jogada, mas como ficaria com 10 bancos de dados?

     

    So pra confirmar eu teria de setar manualmente todos os usuarios cada uma com uma config de identify diferente, teria jeito de ser algo mais automatizado, pois na minha ideia apesar do campo Identify nao pode ser alterado, se pudesse, seria bem mais pratico associar o ID do usuario com o ID do cliente, assim ficaria mais automatico sem precisar ficar setando a cada usuario novo, mas eu queria saber mais sobre a sua ideia pois mesmo assim me parece bem interessante.

     

    Qto ao sincronismo com banco de dados sql o q vc me recomendaria ou me passaria de dica, pois nada melhor trocar ideia com quem ja tem pratica com isso, mas desde ja eu posso dizer que estou bem intrigado com sua ideia do seed e increment.

     

    Um Abraçao

     

     

    segunda-feira, 8 de dezembro de 2008 05:59
  • Como sincronismo posso sugerir que você faça uma replicação do tipo merge. Através da replicação, você pode definir um range a ser usado para cada banco de dados. Ex: quando o PC1 se conectar ao servidor central, ela pega o range de identity de 1 até 10000, já o pc 2 pega do 10001 até o 20000 e assim por diante. Não havendo assim conflitos.

     

    Dessa forma, você não precisaria setar manualmente cada identity. Bastava definir um range que será dado para cada computador. E todas as vezes que o range for complletado, o PC1 pega automaticamente um novo range de 10000 identitys.

     

    Caso não queira usar replicação, pode ficar setando manualmente o range de identitys para cada PC ( banco de dados no caso ).

     

     

    Segue um link que mostra como combinar ranges para várias qtds de databases:

     

    http://www.quest-pipelines.com/newsletter-v4/0903_F.htm

     

    Segue link falando sobre replicação:

     

    http://www.linhadecodigo.com.br/Artigo.aspx?id=1473

     

    Lembre-se, para o seu caso, aconselho o uso da topologia de replicação merge.

     

    Abraços

     

     

    segunda-feira, 8 de dezembro de 2008 12:29
  • Olá amigo,

     

    Marquei a seu post anterior como RESPOSTA, e agradeço muito pela sua atençao!

     

    So para acrescentar a parte de deixar a coisa automatizada poderia entao se fazer algo assim:

     

    Code Snippet

    Abaixo vai a StringSQL para criaçao do banco:

     

     

    "create table t1bTeste(id int identity(1,1), nome char(1))

    GO

     

    insert into tbTeste (nome)values('A')

    insert into tbTeste (nome)values('B')

    insert into tbTeste (nome)values('C')

    GO

     

    select IDENT_CURRENT('tbTeste')

    GO

     

    dbcc checkident('tbteste', reseed, " & UserID * 10000 & ") <--altera o seed que estava em 1 e fica ID do usuario multiplicado por 10000, ou seja, se o ID do usuario for 3 vai começar em 30.000 e assim para cada user

    GO

     

    select IDENT_CURRENT('tbTeste')"

     

     

     

    so  uma duvida, o Replication Mergue nao altera as propriedades Seed e Increment dos bancos para ficar igual a do servidor nao neh ?

     

     

    Abraçao meu amigo e muito obrigado mesmo pela ajuda.

     

    Cordialmente,

    Alexsandro Nunes

    Futura Informatica www.base1.com.br

    segunda-feira, 8 de dezembro de 2008 12:53
  • Olá, o range pode ser definido como vc quiser.

     

    Ex: PC1 de 1 até 10000

          PC2 de 10001 até 20000 e assim por diante.

     

    Na replicação vc pode definir manualmente o range ou pode deixar que cada database pegue seu range conforme falei acina.

     

    Ele nao altera as propriedades nao. Vc pode definir propriedades direntes para cada database.

     

    Abraços

    segunda-feira, 8 de dezembro de 2008 13:02