Fórum Como modificar a chave primária de um registro utilizando LINQ 2 Entities? #12460

02/12/2009

0

Amigos,

Gostaria de atualizar a chave primária de um registro utilizando Linq 2 Entities.
Quando eu faço update via SQL Server Manager, atualizo corretamente o registro, mas quando tento via linq ele diz que não pode atualizar pois a propriedade código faz parte da chave e não pode ser modificada.

Vou passar o script da tabela, e depois meu método de update pra análise:

USE [CONSTRUSYS]
GO

/****** Object:  Table [Fiscal].[OrigemIcms]    Script Date: 12/02/2009 17:46:06 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [Fiscal].[OrigemIcms](
    [codigo] [int] NOT NULL,
    [descricao] [varchar](50) NOT NULL,
 CONSTRAINT [PK_origemIcms] PRIMARY KEY CLUSTERED
(
    [codigo] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING ON
GO




Método de update:

//Altera um registro existente na tabela OrigemICMS
        public void updateOrigemICMS()
        {
            try
            {
                Entities db = new Entities();
                var upOrigemICMS = (from p in db.OrigemIcms
                                    where p.codigo == staticCodigo
                                    select p).First();

                //Implantar mudança de PK
                upOrigemICMS.codigo = this.codigo;
                upOrigemICMS.descricao = this.descricao;

                db.SaveChanges();
                MessageBox.Show(ClassMessages.SucessUpdate);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ClassMessages.ErrorUpdate
                               + ex.Message,
                               "Alterar Origem ICMS");
            }
        }



Daniel Vieira

Daniel Vieira

Responder

Posts

03/12/2009

Luiz Maia

Amigo,   Pq este codigo não é um auto incremento? Tem alguma restrição quando a isto?   Aguardo Att Luiz Maia
Responder

Gostei + 0

03/12/2009

Daniel Vieira

Sim, são os códigos dos impostos do governo.
Por exemplo, a CST, posso ter os valores:

00
10
20
30
40
41
50
51
70
99

etc...

Quem define é o governo, eu vou gerar as telas para o dpto fiscal fazer o cadastro, e se o governo cria um novo, ou altera um exitente, eles possam alterar.
Responder

Gostei + 0

03/12/2009

Luiz Maia

Me mande o erro que esta acontecendo por favor Luiz Maia
Responder

Gostei + 0

03/12/2009

Daniel Vieira


A primeira linha é um texto default feito por mim, a segunda é a exception gerada pelo framework


Responder

Gostei + 0

03/12/2009

Luiz Maia

Daniel, ja não tivemos este mesmo problema ha tempos atras e foi solucionado?   Veja: https://www.devmedia.com.br/suporte/viewtopic.asp?id=11004   Caso seja alguma coisa diferente disto, me diga, ok? Aguardo   Att Luiz Maia
Responder

Gostei + 0

03/12/2009

Daniel Vieira

Luiz, se prestar atenção aquele chamado que eu abri era pra update em chave FK, chave estrangeira.

Esse é pra chave primária PK. Eu tentei e não funcionou com o mesmo método da chave estrangeira.
Responder

Gostei + 0

03/12/2009

Daniel Vieira

Luiz, aquele chamado que eu abri era pra update em chave FK, chave estrangeira.

Esse é pra chave primária PK. Eu tentei e não funcionou com o mesmo método da chave estrangeira.
Responder

Gostei + 0

04/12/2009

Luiz Maia

Daniel,   Desculpe a demora, pois eu tive que desenvolver um projeto similar para eu solucionar. Criei um entidade chamada Atividade, que tem o ID como PK. Veja no codigo abaixo que atualizo o campo ID, o qual eu recupero o registro em questão usando Lambda. Funcionou perfeitamente, veja se consegue esta implementação ai.     public static void Salvar(Entity.Atividade dbAtividade) { Entity.DataClassesDataContext dataClass = new Entity.DataClassesDataContext(); //Verifica se ‚ para atualiza‡Æo da pessoa ou novo plano de a‡Æo if (dbAtividade.Id != 0) { //Busca a organiza‡Æo pelo c¢digo informado para atualizar o registro var Atividade = dataClass.Atividades.Single(pa => pa.Id == dbAtividade.Id); //Autalizando valores do registro retornado com os valores passados Atividade.Id = dbAtividade.Id; Atividade.IdTipoAtividade = dbAtividade.IdTipoAtividade; Atividade.IdPessoa = dbAtividade.IdPessoa; Atividade.IdStatusAtividade = dbAtividade.IdStatusAtividade; Atividade.NomeAtividade = dbAtividade.NomeAtividade; Atividade.DscPorque = dbAtividade.DscPorque; Atividade.DscComo = dbAtividade.DscComo; Atividade.DscOnde = dbAtividade.DscOnde; Atividade.DscObservacao = dbAtividade.DscObservacao; Atividade.DscOrcamento = dbAtividade.DscOrcamento; dataClass.SubmitChanges(); } else { dataClass.Atividades.InsertOnSubmit(dbAtividade); dataClass.SubmitChanges(); } }   Aguardo seu retorno Daniel. Abraços Att Luiz Maia
Responder

Gostei + 0

04/12/2009

Daniel Vieira

Luiz,

Meu Model não reconhece o método

db.SubmitChanges();

Vou testar com o que eu estou acostumado a usar e funciona, o

db.SaveChanges();

vamos ver se roda!
Responder

Gostei + 0

04/12/2009

Daniel Vieira

Meu Model não reconheceu o método submitChanges, e também não reconheceu na expressão lambda o metodo .Single
A propria exception disse que não existe o metodo Single no Linq to Entities, e disse pra usar o metodo first(o que eu utilizo normalmente)

Ficou definido da seguinte maneira:

try
            {
                Entities db = new Entities();

                var upOrigemICMS = db.OrigemIcms.First(pa => pa.codigo == staticCodigo);


                upOrigemICMS.codigo = this.codigo;

                upOrigemICMS.descricao = this.descricao;

                db.SaveChanges();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ClassMessages.ErrorUpdate
                               + ex.Message,
                               "Alterar Origem ICMS");
            }


Acabou gerando o mesmo erro, da primeira vez, mas analisando o codigo, ficou identico ao meu metodo de alteracao, exceto a query, agora esta usando expressao lambda...
Eu estou usando L2E

Sera que voce nao utilizou outra metodologia de acesso a dados?
Responder

Gostei + 0

04/12/2009

Luiz Maia

Sim, me desculpe, acho que usei L2Sql. Vou refazer usando L2E e te mando novamente.   Abraços Att Luiz Maia
Responder

Gostei + 0

04/12/2009

Daniel Vieira

tranquilo fico no aguardo Luiz
Responder

Gostei + 0

06/12/2009

Luiz Maia

Daniel,   Apos um boa pesquisada descobri que não há como alterar um PK no L2E. De acordo com a propria MS, alterar PK ja não é uma regra praticavel, ou seja, nunca se deve faze-la. Isto não é somente regras do L2e e sim uma regra de persistencia de DataBAse. Outra coisa é que o L2E usa Refletion e como nao tera a referencia antiga, não tem como alterar as novas.   Como não conheço suas regras de negocio, e se realmente não houver outra forma de fazer o que quer sem alterar a PK, sugiro que faça uma Stored Procedure a invoque a mesma usando L2E.   Abraços Att Luiz Maia    
Responder

Gostei + 0

07/12/2009

Daniel Vieira

Caramba Luiz, não gostei dessa regra do L2E... Se o próprio SQL Server me permite, porque minha aplicação quer sobrepor a integridade do meu banco? Se for assim eu vou utilizar arquivos txt pra armazenagem, e deixar a aplicação tomar conta de toda a integridade!!

Hehe, desculpe a revolta, mas é que vou ter que modificar a estrutura do meu projeto agora...
Vou ver com o Analista se posso criar uma pk identity, e deixar o codigo como um campo comum, mas o problema é que eles precisam ser fk de outras tabelas, não vai dar certo...

Eu ainda não utilizei sp no L2E, voce poderia me dar um exemplo basico, pra finalizarmos o chamado?
Responder

Gostei + 0

07/12/2009

Luiz Maia

Daniel,   Se vc criar um PK identity, ai que você não vai conseguir alterar mesmo. A unica forma é criar um campo sem ser identity e sem PK, mas acredito que isto o seu DBA não vai concordar.   Para usar um SP no Linq, vc primeiro precisa mapea-la. Pa isto use a Function Import: NO seu arquivo .edmx, botão direito e depois Add > Function IMport.   Segue o exemplo de L2E com SP usando o Nortwind:   set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go


ALTER PROCEDURE [dbo].[CustOrdersOrders] @CustomerID nchar(5)
AS
SELECT *
FROM Orders
WHERE CustomerID = @CustomerID
ORDER BY OrderID     E no codigo:   var db =new NorthwindEntities();
var v=db.CustomerOrders("ALFKI");     So uma dica, dentro da SP vc pode criar uma Tabela temporaria, que sera populada com os dados que precisa, sem se importar com PK, depois vc importa os dados da #tabela para a tabela real.     Abraços Att Luiz Maia    
Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar