Já precisou saber o status de seus dados em determinado ponto do tempo? Entity Framework agora faz isso !
Já pensou em voltar no tempo e conseguir ver como estavam os dados de uma tabela em determinado dia e hora? Isto existe !
O Sql Server já tinha uma feature que eram as “Tabelas Temporais” desde 2016, com um conceito em que é possível obter os dados de uma tabela em qualquer ponto do tempo, ao invés de apenas o último status.
Agora com o Entity Framework Core 6.0 o suporte às tabelas temporais foi disponibilizado e podemos incorporá-lo em nossas aplicações .NET !
Este suporte inclui:
- a criação de tabelas temporais utilizando Migrations
- transformação de tabelas existentes em tabelas temporais utilizando Migrations.
- Consultas à dados históricos
- Restauração de dados em um ponto determinado do tempo.
E como faz pra usar ?
Vamos ver como fica isso em nosso exemplo ? Primeiramente vamos criar um projeto básico MVC com .NET 6 somente para testes.
Nele criaremos uma classe “PessoaModel” para armazenarmos dados de uma pessoa.
Daí precisaremos alterar o contexto do projeto, para informarmos o uso da tabela do tipo temporal ! Para isto, edite o contexto e insira o código para o método “OnModelCreating”, onde deixamos claro que esta entidade “PessoaModel” irá ter uma tabela do tipo “Temporal”.
Feito isso, fazemos uma Migration para gerar o banco de dados, e pelo código, pode-se ver que ele cria um dado específico para auxiliar este controle, nestes dados vemos os campos “PeriodStart” e “PeriodEnd” que armazenarão as datas de vigência daqueles dados, e há um ponto de atenção sobre a visibilidade da coluna onde ela tem um padrão “Hidden” (oculto).
Bom, feito isso, é só editarmos nossos dados à vontade, eu fiz um teste na aplicação criando e alterando um cadastro para ver o seu resultado.
As consultas do Entity pelos meios normais sempre trazem os dados da última versão, a não ser que você especifique diretamente um período no passado.
Já no banco de dados, pude constatar que as diferentes versões são armazenadas, mas numa consulta “normal” eles são ocultados.
Mas com a consulta abaixo utilizado o requisito “SYSTEM_TIME” podemos vê-los.
Legal, mas e se eu precisar obter os dados históricos dentro da minha aplicação?
Então fui até a Controller e simplesmente adicionei esta cláusula para ver todos os registros temporais:
Resultado: minha controller trouxe tudo na tela
Mas também podemos obter os dados de uma forma mais seletiva, se quiser saber em uma determinada data qual eram os dados presentes no registro
Onde os resultados exibidos trouxeram apenas dois registros
Então com esta funcionalidade, podemos ter um histórico das transações de banco quando necessário, porém o próprio Sql Server trata isso de maneira automática fazendo com que consultas comuns não mostrem estes dados.
E também, podemos obter um registro antigo e ao editá-lo torná-lo ativo novamente, como no exemplo da documentação da Microsoft onde obtemos um registro e ao adicioná-lo novamente ao contexto novamente este será salvo e tornado novamente o registro principal.
Para maiores informações, deixo abaixo as referências para que possam também se aventurar e descobrir outras facetas desta funcionalidade.
Já vi tantas situações onde eram criadas tabelas apartadas para o histórico, triggers para fazer este trabalho, vejo que parece ser uma solução bastante interessante pelo lado prático, mas ainda não a testei em produção e com dados massivos para medir performance em comparação com as implementações em tabelas separadas, quem sabe em outro artigo possa aventurar-me nesta medição.
Referências: