Dentro dos diferentes patterns de criação de camadas de acesso dados alguns deles não estão diretamente associados à construção de nossos repositórios, mas estão associados com a adequação da estrutura de nossas entidades a um determinado objetivo.
Este post é sobre um pattern chamado Identity Field.
O padrão Identity Field instrui a utilização de uma propriedade que funcione como chave de identificação de cada entidade das demais, independente do seu tipo de dados, tabela na qual estão salvos ou estrutura.
O objetvo desta chave de identificação é basicamente funcionar como identificador global, que ao contrário dos valores de campos que são chaves primárias (que geralmente são baseados em tipos inteiros, auto-incrementais e que podem se repetir em outras tabelas), agregue uma identificação única daquela tupla no banco de dados e no sistema.
A vantagem de utilizar este tipo de pattern é fazer uso de um identificador global que diferencie as entidades em memória, além de criar uma chave de acesso global que identifique cada entidade das demais no banco de dados.
Relacionado ao conceito dos OIDs…
O uso desta propriedade é semelhante ao funcionamento dos identificadores de objetos (OID, Object Identifiers) dos bancos de dados orientados a objetos. Nos bancos de dados orientados a objetos cada objeto tem um OID, assim cada objeto pode ser visto como um par (OID e Valor). Estes OID sõ gerados automaticamente pelo banco de dados e são imutáveis.
No .Net Framework e no SQL Server?
Com o .Net Framework esta propriedade global pode ser implementada com o tipo de dados GUID (http://en.wikipedia.org/wiki/Globally_unique_identifier), e no caso dos bancos de dados SQL Server, os campos podem ser armazenados com o tipo UNIQUEIDENTIFIER.
No .Net Framework para fazer uso do tipo GUID, e gerar um valor que possa funcionar como identificador global, pode-se usar o método estático NewGuid(), como no exemplo abaixo:
Guid identifier = Guid.NewGuid(); Console.WriteLine(identifier);
E no caso do SQL Server, o identificador pode ser gerado pela função NEWID(), como demonstrado abaixo:
DECLARE @identifier AS UNIQUEIDENTIFIER SET @identifier = NEWID() SELECT @identifier
A estrutura das entidades
O uso desta propriedade implica em duas alterações em nossas entidades:
1 – Criação da propriedade do tipo GUID;
2 – Adoção de um construtor que faça a valorização inicial desta propriedade;
Exemplo:
public class Software { public int Id { get; set; } public string Name { get; set; } public string Version { get; set; } public Guid GlobalId { get; set; } public Software() { this.GlobalId = Guid.NewGuid(); this.Version = this.Name = string.Empty; } }
O valor do identificador desta entidade pode ser visto a seguir:
Para demonstrar o armazenamento de uma entidade no banco de dados utilizarei o Entity Framework Code First. Para tanto, utilizarei o seguinte bloco de código:
Software newSoftware = new Software(); newSoftware.Name = "Visual Studio 2012"; newSoftware.Version = "11.0.0.0"; using (var contexto = new ContextoDados()) { contexto.Softwares.Add(newSoftware); contexto.SaveChanges(); }
Usos
O uso desta propriedade é variado. O uso de identificadores globais é utilizado em cenários como:
– Migração de sistemas
– Unificação de bases de dados
– Exposição de entidades do sistema
– Passagem de parâmetros entre diferentes sistemas
– Passagem de parâmetros para páginas web
– Controles manuais de concorrência
– Sincronização de dados em sistemas desconectados/ambientes off-line
Opinião pessoal
Não sou muito fã da passagem de valores de chaves primárias como parâmetros de query strings em sistemas web. Não gosto da ideia de utilizar estes valores na URL, pois isso é um tanto estranho e incentiva os usuários a ficarem "injetando" valores aleatórios para inferir o carregamento de outros dados.
Desta forma, sempre que preciso passar um ID pela URL, utilizo esse o identificador global, pois é mais seguro do que passar um valor inteiro pela URL, e acaba por evitar a construção de rotinas de criptografia de inteiros e comparação destes valores com dados na fonte de dados.
Por
MSc. Fernando Henrique Inocêncio Borba Ferreira
Microsoft Most Valuable Professional – Visual C#
Referências
http://en.wikipedia.org/wiki/Object_identifier
http://www.objectarchitects.de/ObjectArchitects/orpatterns/index.htm?ObjectLayer/object_layer.htm
http://www.objectarchitects.de/ObjectArchitects/orpatterns/index.htm?OID/index.htm
http://www.martinfowler.com/eaaCatalog/identityField.html
Fernando, amigo! Parabéns pelo post. Uso muito este recurso e concordo com sua postura em relação a pouca segurança de passar Id pela URL
Obrigado Yan! 🙂
Que bom que gostou… realmente é uma prática bacana! Fico feliz por vc utilizar esse recursos 🙂
Obrigado por postar!
Muito bom, mestre.
Curioso, parece que esse recurso é mais usado por fãs de noSql, não acha?
Oi Pri!
Por ser um conceito nascido nos fundamentos dos bancos de dados orientados a objetos, a resposta é sim. É bastante útil 🙂
Sempre o utilizo.
Obrigado por postar, Pri!
bjs
Fernando, realmente bom o post. Tenho uma dúvida.
Você passa na QueryString o GuID completo, pois se você passar não ficar uma URL grande demais? Como você faz? Abraços!
Olá Jean,
Tudo beleza?
Sim, realmente passo o GUID via query string.
Não acredito que fique tão extenso. Fica algo bastante aceitável.
Faça um teste, note que não fica tão extenso. Geralmente qual o tamanho de suas urls?
Existem outros sites que notamos urls mto mais extensas.
Obrigado por comentar!!!
[]s!
Geralmente passo apenas o ID + Alias.
Seria algo assim:
Noticias/10/Brasil_campeao.
Com o GUID não perdemos um pouco no SEO sobre URL’S amigáveis?
Olá Jean,
Tudo beleza?
Acredito que perdemos um pouco comparado com o uso de URLs amigáveis, pois a URL torna-se complexa demais. Mas em compensação temos todos os demais ganhos.
Acredito que em cenários que fazemos uso de URLs amigáveis esse uso não é o mais indicado, mas em outros cenários esse pattern é o ideal.
Obrigado por postar!
[]s!
Eae Fê, blz?!
Cara, esse conceito é muito legal de identificação global. Os exemplos dos cenários são muito pertinentes. Vou colocar no meu canivete suíço 😀
Quanto á URL gostei da colocação do Jean, pois faz diferença sim na SEO.
Em sistemas corporativos a vantagem é indiscutível.
Abs!
Oi Le! Tudo beleza?
Só um detalhe, nós usamos esse pattern no InfraLogs 🙂
[]s!
Olá Fernando, esse pattern tem o mesmo conceito de Surrogate Key que a empresa que trabalho decidiu adotar.
Eu particularmente curto e sempre trabalhei desse jeito, porém surgiu uma dúvida. É correto usar esse pattern para tudo ?Inclusive para tabelas de dominio como: Status, Estado Civil, UF?
Ou seja, ao invés de ter uma tabela com #SG_UF, DS_UF para representar SP, São Paulo ou então #CD_ESTADOCIVIL, DS_ESTADOCIVIL para representar C=Casado, S=Solteiro teríamos que utilizar ID?
Não ficaria estranho utilizar #ID_UF, CD_UF, DS_UF para representar 1, SP, São Paulo ?
Como fazer com os dados de domínio ou sistema?
Olá Carlos!
Tudo beleza?
Não conhecia o pattern por este nome, para mim foi novidade.
Não, não é certo utilizado para tudo. Todo pattern deve ser utilizado para resolver um problema. Se a entidade não tem esse problema então ela não precisa utilizar o pattern.
Obrigado por postar.
[]s!