MetaDapper: Mapeamento e conversão de dados facilitados com as ferramentas certas
Publicados: 2022-03-11A conversão, a tradução e o mapeamento de dados não são de forma alguma ciência do foguete, mas são tediosos. Mesmo uma tarefa simples de conversão de dados (por exemplo, ler um arquivo CSV em uma lista de instâncias de classe) pode exigir uma quantidade de código não trivial. Embora todas essas tarefas tenham muito em comum, todas são “diferentes o suficiente” para exigir seus próprios métodos de conversão de dados.
Em praticamente todos os sistemas que construímos, em algum momento nos encontraremos precisando transformar dados de um formato para outro, seja para importar dados de um armazenamento de dados existente, processar dados de um fluxo de entrada, traduzir de um formato para outro para processamento ou transformação de dados para um formato de saída desejado.
E cada vez que fazemos isso, a tarefa parece tão frustrantemente semelhante ao que fizemos tantas vezes antes, mas tem diferenças suficientes para exigir que façamos o processo de mapeamento de dados novamente, em grande parte do zero.
Além disso, à medida que os formatos e tecnologias mais populares para acessá-los continuam a evoluir, e novos são introduzidos e ganham popularidade, os programadores são obrigados a aprender constantemente novas técnicas de conversão e mapeamento de dados, bibliotecas, APIs e frameworks. À medida que os serviços de ciência de dados continuam a se desenvolver e evoluir, a demanda por ferramentas especializadas também se expande.
Embora você possa aproveitar ferramentas como AutoMapper (para mapear dados de um objeto para outro) ou Resharper (para refatorar código existente), não importa o que você faça, o código será tedioso de escrever e sempre precisará ser mantido. E então você precisa encontrar uma solução para manipulação de tradução entre domínios – como converter códigos internos e valores-chave em valores para outra camada ou sistema, valores nulos em valores padrão, conversão de tipo etc.
A validação tem problemas semelhantes que são abordados por tecnologias como DataAnnotations e o plugin jQuery Validation e por resmas de código de validação personalizado. E as nuances com cada uma dessas tecnologias podem ser bastante sutis.
Como um cientista de dados avançado, você diz a si mesmo “Tem que haver uma maneira melhor”. Bem, na verdade, existe. E é sobre isso que trata este tutorial de mapeamento de dados.
Apresentando a ferramenta de mapeamento de dados MetaDapper
MetaDapper é uma biblioteca .NET que se esforça para simplificar e agilizar o processo de conversão de dados ao máximo.
O MetaDapper facilita a conversão de dados:
- Desacoplar as partes padrão repetíveis do processo de conversão de dados daqueles aspectos que são exclusivos para cada tarefa de transformação de dados.
- Fornecendo uma interface de usuário intuitiva e fácil de usar para especificar regras de mapeamento e tradução de complexidade arbitrária.
O MetaDapper separa o mapeamento lógico (esquema, tradução de dados e validação) do mapeamento de dados físicos (conversão de e para vários formatos de arquivo e APIs). O mapeamento lógico apresenta um poderoso conjunto de funções e permite que você use seus próprios métodos para lidar com necessidades muito específicas. O mapeamento físico inclui um rico conjunto de formatos suportados que estão sendo estendidos constantemente. Para configurar um mapeamento, é fornecido o Configurador MetaDapper; um executável do Windows simples de usar para criar e editar mapeamentos e para executá-los para testes ou para conversões pontuais.
Converter uma lista de instâncias de classe em arquivos XML ou CSV, preencher registros do banco de dados SQL, gerar scripts SQL para preencher tabelas, criar planilhas e muito mais, tudo é feito usando o mesmo arquivo de configuração que geralmente pode ser criado em segundos.
Para incluir o MetaDapper em seu programa .NET, você só precisa:
- Adicionar uma referência à biblioteca
- Instanciar o mecanismo MetaDapper
- Execute o mapeamento, especificando o leitor de origem (e quaisquer parâmetros), o gravador de destino (e quaisquer parâmetros) e seu arquivo de configuração.
Em caso de sucesso, o gravador produzirá os dados transformados. Em caso de erro, uma exceção retornará informações detalhadas do erro para que você possa rejeitar os dados ou ajustar a configuração.
Aqui está um breve exemplo de mapeamento de dados:
List<MyClass> result; try { // Instantiate the MetaDapper library. var log = new Log(); var cultureInfo = new CultureInfo("en-US"); var md = new MetaDapper.Engine.MetaDapper(log, cultureInfo); using (var inputStream = new StreamReader(@"C:\myfile.csv")) { md.MapData( new CsvReaderParameters { Log = log, CultureInfo = cultureInfo, InputStream = inputStream.BaseStream, InputEncoding = Encoding.ASCII, FirstRecordIsHeader = false }, new PublicPropertiesWriterParameters { Log = log, CultureInfo = cultureInfo }, @"C:\MyMetaDapperConfiguration.xml", false, out result); } } catch (Exception) { throw; }
O “Configurador” do MetaDapper
O MetaDapper Configurator fornece uma maneira de percorrer visualmente as etapas de definição de sua estrutura de dados e regras de conversão/mapeamento. O Configurador permite que você crie, edite e execute configurações (ou seja, para testes ou conversões pontuais).
O Configurador do MetaDapper se esforça para automatizar o máximo possível do processo. Por exemplo, ao especificar um mapeamento de campo, os campos de origem e destino são correspondidos automaticamente quando possível usando a correspondência de nomes. Além disso, ao criar Definições de Registro para fontes de dados que contêm metadados, as definições de campo podem ser preenchidas automaticamente apontando para a fonte de dados.
Uma vez criada, uma Definição de Registro mantém seu link para a fonte de dados da qual foi criada (se houver) para que possa ser atualizada automaticamente se o esquema da fonte de dados for alterado posteriormente. Ao configurar uma definição de registro para uma fonte de dados com pouco ou nenhum metadados disponível, se outra fonte de dados semelhante estiver disponível que contenha metadados, essa definição de registro pode ser copiada (com seus metadados) para servir como base para a nova definição de registro e pode então ser editado para refletir quaisquer diferenças que possam existir entre as duas fontes de dados. E nos casos em que o esquema e os metadados são idênticos para várias fontes de dados, uma única definição de registro pode ser usada para todos eles.
Simplificando o processo de conversão de dados
Vejamos com mais detalhes alguns dos desafios inerentes ao processo de conversão de dados e as maneiras pelas quais o MetaDapper os facilita e simplifica para o desenvolvedor.
Mapeamento de origem para dados de destino
Quando uma estrutura interna ou externa é alterada durante a manutenção, qualquer código de mapeamento que dependa dessas estruturas também pode precisar ser ajustado. Esta é uma área onde o trabalho de manutenção é frequentemente necessário, portanto, qualquer que seja a solução que você use, os custos de manutenção precisam ser avaliados. Por exemplo, se uma propriedade TotalSale for removida de uma classe Sale, quaisquer atribuições de mapeamento relacionadas precisarão ser ajustadas adequadamente.
Com o MetaDapper, a atualização de um mapeamento pode levar apenas alguns segundos. Para um tipo de classe, por exemplo, basta clicar no botão “Importar definições de campo da classe” para atualizar os campos para a definição recém-compilada:
Conversão de tipo
Algumas conversões de tipo, como conversões de tipo Data/Hora e Número, por exemplo, são sensíveis às configurações internacionais do ambiente do host (a menos que explicitamente especificadas no código). A implantação de um aplicativo em um novo servidor com configurações internacionais diferentes pode, portanto, quebrar o código que não leva isso em consideração. Um valor de data de “1-2-2014”, por exemplo, será interpretado como 2 de janeiro de 2014 em uma máquina com configurações dos EUA, mas como 1º de fevereiro de 2014 em uma máquina com configurações do Reino Unido. O MetaDapper suporta todas as conversões .NET implícitas e também permite a reformatação complexa de valores como parte da tradução. Além disso, configurações internacionais separadas (ou seja, independentes) podem ser especificadas nos leitores, gravadores e no mecanismo de mapeamento do MetaDapper.
Valores padrão complexos
Às vezes, são necessárias regras de negócios específicas que exigem acesso a outros sistemas ou codificação complexa para determinar um valor padrão. O MetaDapper permite que qualquer número de métodos delegados personalizados sejam registrados no mecanismo e empregados para fornecer valores padrão, realizar conversão de dados personalizados e fornecer validação de campo personalizado.
Regras de validação condicional
Não é incomum que os valores dos campos sejam exigidos condicionalmente (ou mesmo que seus valores válidos sejam dependentes dos valores de outros campos). Por exemplo, pode ser que os campos Nome do parceiro e Código de previdência social do parceiro possam ser deixados em branco, mas se um Nome do parceiro for fornecido, o Código de previdência social do parceiro (e possivelmente outros campos) deverá ser fornecido. Esse tipo de validação condicional é complexo e fácil de errar no código personalizado. Por outro lado, o MetaDapper permite que esse tipo de relacionamento de mapeamento de dados seja facilmente configurado. Especificamente, uma lista de campos em uma definição de registro pode ser listada em um grupo de campos obrigatórios condicionais:

Então, em um mapeamento, o grupo pode ser associado a qualquer campo que, se não for nulo, exigiria que todos os campos do grupo fossem fornecidos. Por exemplo:
Convertendo valores mapeados entre domínios
Os dados de origem podem conter valores inconsistentes. Por exemplo, um campo de saudação pode conter “Mr.”, “Mr”, “MR.”, “Mister” ou “M”, bem como todos os equivalentes femininos. Ou um campo de moeda pode conter um valor como “$” enquanto seu formato de destino requer “USD”. Os códigos de produto são outro exemplo de valores que podem precisar ser convertidos de um sistema para outro. O MetaDapper permite a especificação de “listas de sinônimos” reutilizáveis que podem ser usadas para traduzir valores durante mapeamentos.
Uma vez definido, você pode especificar o Grupo de Sinônimos para empregá-lo em qualquer mapeamento de campo relevante:
Mapeamentos baseados em formatação de valores e cálculos complexos
Os valores de um ou mais campos podem precisar ser usados para formatar um novo valor. Por exemplo, o valor de origem pode precisar ser decorado com constantes (por exemplo, sale.PriceEach = "$" + priceEach;
) ou vários campos podem precisar ser usados para gerar um valor (por exemplo, sale.Code = code1 + “_” + code2;
).
O MetaDapper fornece um recurso de formatação/modelagem que permite criar valores usando qualquer um dos campos no registro atual, incluindo partes de substring de campos ou valores constantes. Após a formatação, o valor será convertido para o tipo de destino especificado (que, aliás, não precisa ser uma string).
Da mesma forma, cálculos complexos podem ser realizados durante os mapeamentos, empregando um conjunto completo de operadores matemáticos e funções em qualquer combinação de valores de campo e constantes.
Regras de validação
Os delegados de validação personalizados podem ser registrados e usados em mapeamentos. Aqui está um exemplo de um método personalizado para validar que um valor de campo é um inteiro (sem tornar o tipo de dados do campo um inteiro):
private static bool ValidateIsInteger( Log log, CultureInfo cultureInfo, object value, ref List<ErrorInfo> errors) { try { Convert.ToInt32(value); } catch (Exception) { return false; } return true; }
O método seria registrado ao instanciar o MetaDapper. Então, pode ser facilmente aplicado em qualquer definição de mapeamento de campo:
Agrupar, classificar e filtrar
As operações de agrupamento e classificação geralmente podem ser tratadas em uma consulta de banco de dados, mas nem todas as fontes de dados são bancos de dados. O MetaDapper, portanto, suporta a configuração de operações complexas de agrupamento e classificação que podem ser executadas na memória.
Nos casos em que apenas uma parte dos dados de origem pode ser necessária, a filtragem de origens que não são de banco de dados pode ser muito complexa de implementar e manter. O MetaDapper suporta a configuração de filtros complexos com operadores booleanos para qualquer número de avaliações de campo por registro, com aninhamento de operações arbitrariamente profundo conforme necessário. Por exemplo:
O filtro acima é equivalente ao seguinte código C#:
if (sale.TransactionID > “0” AND sale.Currency == “USD” AND (sale.Amount > “3” || sale.Amount == “1”)
Mapeamentos aninhados
Alguns mapeamentos exigem várias passagens para concluir o processo de conversão de dados. Alguns exemplos incluem dados que requerem registros de prefixo ou soma, dados que precisam ser mapeados de forma diferente dependendo dos valores de campo ou estrutura do documento, ou simplesmente para isolar diferentes estágios de um mapeamento complexo (ou seja, traduzir nomes, conversões de tipo, etc.). Para esse fim, o MetaDapper suporta mapeamentos aninhados para qualquer nível de profundidade.
Formato vs. estrutura
Como uma ferramenta de mapeamento e conversão de dados, o MetaDapper é construído para permitir que praticamente qualquer formato de dados seja lido ou gravado usando interfaces internas de leitor e gravador. Isso permite a criação de classes de leitor/gravador extremamente leves e focadas apenas nas nuances específicas do formato.
Leitores e escritores também se comportam da maneira mais inteligente e flexível possível. Por exemplo, o leitor e gravador de XML emprega XPaths para especificar onde recuperar ou gravar dados em um arquivo XML. A mesma configuração também pode ser usada para ler e gravar, por exemplo, de formatos não XML (como arquivos CSV), caso em que os valores XPath serão simplesmente ignorados. Da mesma forma, se uma configuração que não inclui configurações de XPath for usada com um leitor ou gravador de XML, um erro será gerado.
Sim. Certo. Certo. (Alguns exemplos de mapeamento de dados reais)
Você está cético. E eu não te culpo. As ferramentas de software raramente são tudo o que dizem ser. Então, aqui estão alguns exemplos do mundo real onde o MetaDapper já foi usado para fornecer benefícios operacionais.
Uma empresa que fornece software de gerenciamento de seguro médico tinha clientes que não queriam preencher formulários da web, mas queriam fornecer seus dados em planilhas. Usando o MetaDapper, as planilhas carregadas são lidas na memória, os dados limpos, os registros validados e os resultados armazenados em seu banco de dados. Eles podem aceitar arquivos Excel de seus clientes sem qualquer validação humana usando o MetaDapper com um arquivo de configuração fácil de criar para cada modelo de planilha que publicam.
Uma grande empresa de gás possui um aplicativo interno e queria que seus usuários gerenciais pudessem fazer download de relatórios em formato Excel. Os formatos de relatório provavelmente seriam alterados regularmente. O MetaDapper facilitou a geração de planilhas do Excel a partir de seu banco de dados. A atualização dos formatos do Excel exigia apenas a atualização dos arquivos de configuração do MetaDapper sem qualquer alteração de código ou recompilação.
Uma empresa que fornece software de gerenciamento de ativos precisava de uma solução para gerar dados financeiros em formatos de pacotes de contabilidade dependentes do cliente para importação nesses sistemas. Uma consulta genérica de dados contábeis foi desenvolvida usando um wrapper ORM e o MetaDapper foi usado para classificar, filtrar e mapear os dados no esquema e formato desejados para cada cliente. Uma ou mais configurações do MetaDapper são feitas para cada cliente e isso se tornou um importante recurso de venda para novos clientes. O produto pode ser configurado (usando o MetaDapper) em minutos para suportar qualquer formato de pacote de contabilidade personalizado ou padrão, de modo que a integração com sistemas essenciais e existentes seja incluída em cada nova venda. A mesma empresa utiliza o MetaDapper em diversos projetos de integração de software, mapeando e convertendo dados e convertendo códigos internos entre seus sistemas.
Um grande revendedor de automóveis precisava adicionar alguns relatórios de vendas em formato Excel a um de seus aplicativos. Os relatórios foram adicionados ao aplicativo em menos de uma hora – do início ao fim.
Um desenvolvedor precisava de uma tabela de estados dos EUA idêntica ao conjunto usado em outro site. O MetaDapper foi usado para extrair os dados do site e gerar um script SQL para preencher sua tabela em poucos minutos.
Estes são apenas alguns exemplos da utilidade e valor comprovados do MetaDapper como ferramenta de mapeamento de dados.
Embrulhar
É preciso um salto mental para começar a pensar na conversão de dados de forma mais genérica e começar a pensar em conjuntos de dados com regras de negócios e utilidade ilimitada. MetaDapper é uma estrutura que promove e facilita essa perspectiva.
Se você usa o MetaDapper, outra tecnologia ou lança suas próprias soluções de mapeamento de dados, esta foi uma introdução a algumas das complexidades e custos ocultos em projetos de conversão de dados. Espero que você ache informativo.
(Para obter mais informações sobre o MetaDapper, entre em contato com a equipe do MetaDapper em [email protected].)