Fórum Como modificar a chave estrangeira de um registro utilizando Linq to Entities? #11004
03/11/2009
0
O cenário é o seguinte:
Tenho um registro de Produto que contém o seu código identity como chave primária.
Esse registro contém várias chaves estrangeiras, entre elas CódigoGrupo, CódigoGrupoSub, CódigoFamília.
Eu gostaria de fazer uma atualização em alguns registros, modificando as chaves estrangeiras apenas.
Ex:
Id Descrição Grupo SubGrupo Familia
1 Cimento 1 1 1
2 Cal 3 2 1
3 Tijolo 4 3 4
4 Bloco 1 1 9
Eu gostaria de reorganizar esses produtos, modificando seus Grupos, SubGrupos, Famílias.
Quando eu edito diretamente na base de dados (SQL Server 2008), o banco me deixa atualizar perfeitamente, apenas restringe se realmente existe os novos registros de Grupo, Subgrupo e Familia nas tabelas correspondentes.
Portanto eu posso passar de Grupo 6, SubGrupo 3, Familia 9 para Grupo 10 Subgrupo 10 Familia 10, desde que os segundos registros existam em suas tabelas respectivas.
Mas quando eu tento update via aplicação, utilizando Linq to Entities, eu obtenho a seguinte mensagem:
A propriedade 'codigoGrupoSubFamilia' faz parte das informações de chave do objeto e não pode ser modificada.
A mensagem vem em português mesmo, estou utilizando a versão traduzida do VS2008 e do SQL Server 2008 (que eu pessoalmente não gosto, mas a empresa optou pela versão traduzida).
Utilizando linguagem c#.
No aguardo, e se necessário posso postar scripts, métodos, código, qualquer coisa que seja necessária.
Daniel Vieira
Curtir tópico
+ 0Posts
04/11/2009
Luiz Maia
r.cityReference.EntityKey = new EntityKey("YourEntitiesNamespace.cities", "city_id", 5); Exemplo acima: Note que o "record" tem a propriedade cityReference, que no seu caso sera familiaReference e assim por diante... Esta propriedade é automaticamente gerada edmx justamente por causa da referencia em outra entidade(table). Este new EntityKey tem apenas 3 parametros: 1 - qualifiedEntitySetName(string): que sera o entityNameSpace.TableName. 2 - KeyName(string): campo da PK 3 - KeyValue(object): valor do campo PK Espero ter ajudado. Aguardo seu retorno, ok? Referencia: http://stackoverflow.com/questions/826537/how-do-i-update-an-objects-foreign-key-value-with-linq-to-entities Abraços Att Luiz Maia
Gostei + 0
04/11/2009
Daniel Vieira
r.cityReference.EntityKey = new EntityKey("YourEntitiesNamespace.cities", "city_id", 5); Exemplo acima: Note que o "record" tem a propriedade cityReference, que no seu caso sera familiaReference e assim por diante... Esta propriedade é automaticamente gerada edmx justamente por causa da referencia em outra entidade(table). Este new EntityKey tem apenas 3 parametros: 1 - qualifiedEntitySetName(string): que sera o entityNameSpace.TableName. 2 - KeyName(string): campo da PK 3 - KeyValue(object): valor do campo PK
Eu utilizo o L2E exatamente pelo que você disse, estamos no meio do projeto, e o início do projeto foi adquirido de terceiros, nem tivemos opção.
A propriedade Reference eu utilizo Reference.Value pra atribuir a referencia da FK em um novo registro a ser gravado.
newProduto.GrupoSubFamiliaReference.Value = newGrupoSubFamilia;
Agora EntityKey eu nunca utilizei, e acabei não entendendo os parâmetros muito bem.
Poderia me dar um exemplo, utilizando a minha nomenclatura?
Tabela pai (que eu quero atualizar as fks)
Produto
Tabelas estrangeiras
Grupo
GrupoSub
GrupoSubFamilia
Digamos que eu quero atualizar o Campo codigoGrupoSubFamilia do registro de Produtos, de 3 para 1, qual seriam os parâmtros que eu teria que passar?
Gostei + 0
04/11/2009
Daniel Vieira
Eu utilizo o L2E exatamente pelo que você disse, estamos no meio do projeto, e o início do projeto foi adquirido de terceiros, nem tivemos opção.
A propriedade Reference eu utilizo Reference.Value pra atribuir a referencia da FK em um novo registro a ser gravado.
newProduto.GrupoSubFamiliaReference.Value = newGrupoSubFamilia;
Agora EntityKey eu nunca utilizei, e acabei não entendendo os parâmetros muito bem.
Poderia me dar um exemplo, utilizando a minha nomenclatura?
Tabela pai (que eu quero atualizar as fks)
Produto
Tabelas estrangeiras
Grupo
GrupoSub
GrupoSubFamilia
Digamos que eu quero atualizar o Campo codigoGrupoSubFamilia do registro de Produtos, de 3 para 1, qual seriam os parâmtros que eu teria que passar?
Gostei + 0
04/11/2009
Luiz Maia
Gostei + 0
04/11/2009
Daniel Vieira
Pra esclarecer melhor vou postar a organização das tabelas:
tblGrupo
codigoGrupo
Descricao
tblGrupoSub
codigoGrupo FK
codigoGrupoSub
Descricao
tblFamilia
codigoGrupo FK
codigoGrupoSub FK
codigoGrupoSubFamilia
Descricao
tblProduto
codigoProduto
Descricao
codigoGrupo FK
codigoGrupoSub FK
codigoGrupoSubFamilia FK
Campos sublinhados são PK
Eu preciso trocar os valores das 3 FKs na tabela de produto.
Pra navegar entre os 3 valores eu tenho acesso apenas navegando Produto.GrupoSubFamilia
Pra trocar esses 3 valores como ficaria o exemplo?
Gostei + 0
04/11/2009
Luiz Maia
Gostei + 0
04/11/2009
Daniel Vieira
Uma família número 1 pode pertencer ao Grupo 1 + SubGrupo 1, e pode também pertencer ao Grupo 1 + Subgrupo 2.
Ex
Grupo GrupoSub Familia
1 1 1
1 2 1
1 2 2
1 2 3
A chave é baseada na composição das chaves anteriores
Gostei + 0
04/11/2009
Daniel Vieira
Olha o MER pra ficar mais claro
Gostei + 0
04/11/2009
Luiz Maia
Gostei + 0
04/11/2009
Daniel Vieira
Mas o da produto esta em branco, da uma olhada:
GrupoSubFamilia
Produto
Gostei + 0
04/11/2009
Luiz Maia
Gostei + 0
04/11/2009
Daniel Vieira
Eu cliquei diretamente na tabela, clicando no mapeamento ficaria assim:
Gostei + 0
04/11/2009
Daniel Vieira
transfProduto.UnidadeMedidaReference.EntityKey =new EntityKey(
"Entities.UnidadeMedida",
"codigoUnidadeMedida",
"L");
Quando eu tento atualizar as chaves de GrupoSubFamilia, utilizando
transfProduto.GrupoSubFamiliaReference.EntityKey = new EntityKey(
"ModelDB.GrupoSubFamilia",
"codigoGrupoSubFamilia",
codGrupoSubFamilia);
Eu recebo a seguinte mensagem:
A lista de pares chave-valor fornecida contém um número incorreto de entradas. Há 3 campos de chave definidos no tipo 'CONSTRUSYSModel.GrupoSubFamilia' mas 1 foram fornecidos.
Nom do parâmetro: value
A mensagem vem em português.
Deve ser porque estou passando apenas 1 das chaves, e ela é chave composta.Como eu passaria os outros valores?
Gostei + 0
04/11/2009
Luiz Maia
new AdventureWorksEntities())
{
try
{
Object entity = null;
IEnumerable<KeyValuePair<string, object>> entityKeyValues =
new KeyValuePair<string, object>[] {
new KeyValuePair<string, object>("SalesOrderID", 43680) };
// Create the key for a specific SalesOrderHeader object.
EntityKey key = new EntityKey("AdventureWorksEntities.SalesOrderHeader", entityKeyValues);
// Get the object from the context or the persisted store by its key.
if (advWorksContext.TryGetObjectByKey(key, out entity))
{
Console.WriteLine("The requested " + entity.GetType().FullName +
" object was found");
}
else
{
Console.WriteLine("An object with this key " +
"could not be found.");
}
}
catch (EntitySqlException ex)
{
Console.WriteLine(ex.ToString());
}
} Aqui a referencia completa da MS: http://msdn.microsoft.com/en-us/library/dd283138.aspx Vaja que são criados pares de chaves no exemplo acima: IEnumerable<KeyValuePair<string, object>> entityKeyValues =
new KeyValuePair<string, object>[] {
new KeyValuePair<string, object>("SalesOrderID", 43680) };
Isto se deve a sobrecarga deste metodo existente no new EntityKey. Aguardo Att Luiz Maia
Gostei + 0
04/11/2009
Daniel Vieira
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)