Migrando XML para SQL Server com Entity Framework

Download do Código-Fonte

O objetivo deste post é ajudar os leitores a realizar uma tarefa muito penosa e que por mais de uma vez eu já tive de fazer: migrar bases de dados XML para algum banco de dado Entidade-Relacional, como SQL Server, MySQL, etc. O cenário é o seguinte: por algum motivo você tem um arquivo XML contendo dezenas, centenas, MILHARES de informações muito úteis para seu sistema (como um arquivo contendo todas as cidades brasileiras, por exemplo) mas não-curte/não-quer usar Linq To SQL para manipular o XML como se fosse uma base de dados. O que você quer na verdade é apenas pegar aquelas informações e colocar em seu banco de dados favorito. Cadastrar tudo na mão usando Inserts? ‘Tá maluco? Este é o objetivo do post de hoje: como migrar um XML para uma base de dados, como exemplo, o SQL Server.

Veremos neste post:

  1. Ingredientes
  2. Preparativos
  3. Mãos à obra
  4. Considerações Importantes

Vamos lá!

Ingredientes

  • Nós vamos precisar de um Visual Studio 2010 (pode ser a excelente versão Express distribuída gratuitamente neste link).
  • Também iremos utilizar uma base de dados Entidade-Relacional de sua preferência. Em nosso exemplo utilizaremos o SQL Server 2008 R2 (também possui versão Express gratuita neste link). Se for utilizar outra base como Oracle, Postgre SQL ou MySql, não esqueça de baixar seu conector .NET nos sites dos desenvolvedores desses bancos para que o Visualo Studio reconheça os mesmos.
  • Um arquivo XML contendo muitas informações úteis que você deseja inserir no banco. No exemplo utilizaremos nosso Estados.xml, disponibilizado no post anterior.
  • Muita vontade de ler este blogueiro chato!

Preparativos

Abra seu VS2010 e crie um novo projeto do tipo Console Application.

Nada impede que você utilize outro projeto, é apenas mania minha criar Consoles Applications para scripts desse tipo.

A receita aqui é velha: File -> New | Project -> Visual C# | Windows | Console Application. Dê o nome que quiser (Xml2Bd no meu caso) e toca ficha na criação. Note que vamos deixar a versão do Framework como 4, conforme o padrão do VS2010.

Porque não podemos utilizar na versão 3.5? Duas palavras: Entity Framework.

O Entity Framework surgiu como uma feature adicional ainda durante a versão 3.0 do Framework .NET e foi incorporado definitivamente na versão 3.5, porém (sempre tem um porém…) era uma porcaria.

Isso mesmo, a versão inicial do EF possui muitos bugs largamente conhecidos entre a comunidade de desenvolvedores como rastreamento de objetos, contexto de objetos, desenvolvimento em N camadas e por aí vai. Boa parte desses bugs foram solucionados na nova versão, presente no Framework 4. Por isso você está fazendo um favor a si mesmo se não perder tempo tentando usar o EF do Framework 3.5, vai por mim.

Este tutorial espera que você tenha os conhecimentos necessários para criar sozinho uma base de dados no SQL Server utilizando o fantástico SQL Server Management Studio (se estiver com preguiça, use o script SQL pronto que deixei dentro da Solution para download no início deste tuto).

Você precisará de um banco de dados com o nome de Xml2Bd contendo uma única tabela Estado (o singular é proposital mas não obrigatório) com as seguintes colunas: ID (int, PK), IDCapital (int), Sigla (char[2]) e Nome (nvarchar[50]). Este é o banco onde serão armazenados os dados do XML.

Se for fazer este exemplo com o xml de cidades também, não esqueça de adicionar uma tabela Cidade no banco contendo as devidas colunas. A figura abaixo mostra como seu banco deve se parecer para que o script que criaremos a seguir funcione corretamente.

Note que não criei o relacionamento das tabelas, pois isso faria com que não conseguíssemos inserir Estados antes de cidades e vice-versa por causa das restrições de Foreign Keys. Também não deixei os IDs das tabelas como auto-incremento pois no próprio XML já está contido os IDs de cada registro.

O próximo passo é adicionar o arquivo XML ao seu projeto.

Crie uma pasta XML e jogue lá dentro o dito-cujo, no nosso caso, o Estados.xml. Sem figura para esta etapa, todo mundo está careca de saber que basta clicar o botão direito do mouse sobre o projeto e ir em Add | New Folder para criar a pasta e em Add | Existing Item para adicionar o arquivo na pasta.

No passo seguinte (ok, desta vez coloco figura) adicione um novo item ao projeto seguindo o caminho Add | New Item -> Visual C# | Data | ADO.NET Entity Data Model. Coloque o nome de ContextoDados e clique em Add. Este arquivo com a extensão .EDMX nada mais é do que um mapeador objeto-relacional. Só isso.

Ok eu explico: esse arquivo .EDMX com o nome de ContextoDados conterá informações sobre o banco de dados que você criou no passo anterior, ele vai mapear cada uma das tabelas que existem lá e criar classes para elas, facilitando o manuseio. Através dos próximos passos você vai entender isso melhor.

Iniciará o Entity Data Model Wizard, um assistente para mapeamento do seu banco. No primeiro passo deixe a opção “Generate from Database” marcada e clique em Next. Na tela seguinte (Choose your data connection), clique em “New Connection” para adicionar uma conexão com seu banco de dados (criado lá no início, lembra?) ou apenas selecione ela no ComboBox se estiver aparecendo (meu caso). Clique em Next.

Em seguida (Choose your database objects) você deve selecionar quais objetos do seu banco você deseja mapear. No nosso caso, selecione apenas a tabela Estado (ou Cidade também, se a incluiu no banco como eu) e mantendo as demais configurações por padrão, clique em Finish.

Ao concluir o processo, serão adicionadas algumas referências ao seu projeto, bem como o arquivo EDMX citado anteriormente. O VS2010 também já deixará o dito arquivo aberto para que você visualize o resultado do mapeamento em um diagrama semelhante aos ER tradicionais. Agora você tem o XML com os dados e o banco devidamente mapeado para objetos (cortesia do EF), go code!

Mãos à Obra!

Depois dessa preparação que mais pareceu tarefa de setor de infraestrutura (NNF na gíria deles), vamos finalmente ao que interesse: o código!

Basicamente o que faremos aqui será o seguinte: analisaremos o arquivo XML de estados e para cada estado lá presente, instanciaremos uma classe Estado (criada automaticamente pelo EF durante o mapeamento), preencheremos suas propriedades com os valores do XML e salvaremos ela no ContextoDados, que por sua vez salvará no banco. Simples assim.

Obviamente isso exige algum conhecimento de Linq To XML, que não será coberto neste post (quem sabe futuramente?) mas que não faltam informações no Tio Google. Sim, eu darei os scripts de Linq To XML, mas seria bom se você realmente estudasse um pouco mais porque é realmente muito poderoso trabalhar com XML desta forma.

Começamos nosso código abrindo o arquivo XML com Linq2Xml e imprimindo todos seus estados no console. Esse código vai dentro do método Main no arquivo Program.cs de sua Console Application.

Note que o caminho do arquivo XML deve ser alterado para condizer com a sua realidade. Se tudo der certo, o Console exibirá o nome de todos os estados existentes no XML. Importante: não esqueça de adicionar uma diretiva using no topo do seu código para o namepsace System.Xml.Linq ou ele não vai compilar.

Se você fez o exemplo anterior de forma correta, já imagina como proceder para terminar o script sozinho, mas vamos terminar juntos. Incremente seu código conforme o exemplo abaixo, fazendo com que você instancie um Xml2BDEntities (nome gerado automaticamente para o contexto de dados do nosso banco Xml2Bd) e adicione um novo objeto Estado para cada registro Estado no XML.

Voilá! Aqui temos nosso código de migração XML para Sql Server 100% pronto! Se você for na sua tabela de Estados encontrará  todos os registros devidamente inseridos. O código para inserir as cidades no banco é praticamente o mesmo, mudando apenas a entidade a ser salva (Cidade) e os elementos do XML a serem percorridos. O referido código se encontra 100% pronto na solution que disponibilizei para download no início do post, se o que você queria era apenas co0locar os estados e cidades dos arquivos no seu BD, basta executar.

Considerações Importantes

Note que tive uma preocupação importante neste código que foi a de não instanciar múltiplos contextos de dados (Xml2BdEntities) para não sobrecarregar a memória do programa e nem encher o banco de requisições inúteis. Também efetuei somente uma operação de inserção no banco contendo todos os registros a serem adicionados, feito evidenciado pela chamada contextoDados.SaveChanges() na última linha de código, que nada mais faz do que persiste as entidades alteradas diretamente o banco de dados físico.

Essas preocupações são o mínimo que se espera de um código ágil (afinal chamadas repetitivas ao banco de dados tornam a aplicação lenta) e escalável (nunca subestime a sua capacidade de escrever programas que derrubem a pilha de memória do servidor). E se eu quisesse migrar informações de uma base MySQL para uma SQL Server? Esse assunto foi abordado nesse post.

Por hoje é só pessoal. Até o próximo post!

Base de dados com todos estados e cidades brasileiras

Há alguns meses atrás estava desenvolvendo uma aplicação e por um motivo específico da mesma eu necessitava de uma base de dados com todos os estados brasileiros, todas cidades brasileiras, saber as capitais de cada estado e os DDDs de cada cidade. Dei várias “Googladas” e não encontrei nada. Ao que parece ninguém disponibilizou tal base de dados publicamente, embora todos esses dados sejam públicos e facilmente encontrados em sites como do IBGE. Como “coder” que sou, acabei desenvolvendo um script que lia uma página do IBGE e retirava as informações que me importavam, neste caso, a lista de cidades de cada estado. Mais uns minutos pesquisando e obtive as informações do DDD através do site da Embratel. Atando as pontas e mais um pouco de código e voilá! Uma base de dados prontinha contendo todas as informações geo-políticas das quais necessitava!

Como todo bom samaritano, tratei de guardar tal base para disponibilizá-la mais tarde quando tivesse um blog próprio. Opa! Segue abaixo o link para download de dois arquivos XML. O Estados.xml contém os dados referentes aos estados brasileiros, suas siglas e capitais. No Cidades.xml você tem uma imensa lista que acredito que abranja no mínimo 90% das cidades brasileiras (a culpa é do site do IBGE que é desatualizado) com o estado ao qual pertence e seu DDD (sim, não é apenas um DDD por estado). O quê, você não sabe como fazer para transformar esse XML na sua base de dados favorita? Então não perca meu próximo post

Se você acabar utilizando tais arquivos em seu sistema, não esqueça de por meu nome nos agradecimentos, hehehehe.

Update em 02/01/2010: um pedido de desculpas aos leitores mineiros. Acabei de atualizar os arquivos com o estado de Minas Gerais (Estados.xml), as cidades de Minas Gerais (Cidades.xml) e para compensar o erro, adicionei um outro XML para download, o Regioes.xml com dezenas de regiões do Brasil, como Baixada Santista, Serra Gaúcha, entre outras, para facilitar a vida de quem esteja desenvolvendo (assim como eu) aplicações que usam dados geográficos como filtro para alguma busca. Agora o arquivo de cidades possui 5537 cidades brasileiras, bem pertinho dos 5565 aproximados que o IBGE diz que nosso Brasil possui.

Blog novo na área!

Olá! Provavelmente você caiu neste blog sem querer, afinal acabei de criá-lo e não tem nada que preste aqui. Entretanto, antes que desista de ler este post, quero que entenda o que vai aparecer por aqui daqui pra frente.

O LuizTools é uma idéia antiga e amadurecida ao longo dos meus quase 4 anos como desenvolvedor na plataforma .NET. De lá para cá criei muitos softwares que foram úteis para mim e para meus amigos, agora pretendo expô-los em forma de ferramentas web para que todos possam ter acesso e comprovar sua utilidade (ou não). Além disso, O LuizTools será a representação web do que se passa na minha cabeça. Em termos de programação é claro!

Por aqui passarão dúvidas e suas respectivas soluções, frustrações com certas tecnologias, certos frameworks, certos softwares e por aí vai. Desabafarei com relação a projetos em que esteja envolvido e falarei um pouco de nerdices em geral, conforme me vier à cabeça, como gadgets, filmes, RPG, games e “sei-lá-mais-o-quê”.

Um pouco sobre mim

Meu nome é Luiz Fernando e tenho atualmente 22 anos. Sou (quase) casado, Reparador de Equipamentos Eletrônicos pelo SENAI Gravataí e formado recentemente em Ciência da Computação pela ULBRA Gravataí, cidade na qual resido há 12 anos. Trabalho há 3 anos como desenvolvedor de sistemas web (ASP.NET) na RedeHost, também em Gravataí, embora tenhamos nossa infraestrutura dividida entre Porto Alegre e São Paulo. Antes disso desenvolvi com C/C++, Java e Assembly, em empresas como a InterServicer (antiga GeroServicer), Criterium, CWI Software e até mesmo no CPD da Secretaria de Saúde de Gravataí (meus tempos negros como infraestrutura-man). Ah, também sou certificado como Professional Scrum Developer e Professional Scrum Master I, pela Scrum.org.

Quando não estou trabalhando desenvolvo projetos pessoais (como este blog), ministro treinamentos em ASP.NET e SQL Server em instituições de ensino superior como FAQI e Facensa, e até mesmo internamente na RedeHost. Ok, volta e meia jogo um pouco de videogame, geralmente algum Pro Evolution Soccer ou Need for Speed, gêneros que curto acima de qualquer outro. Também saio com minha namorada porque ninguém é de ferro. Atualmente estou em busca de um professor particular de inglês para aprimorar minha fluência no idioma.

Então é isso, bem vindo ao Luiz Tools!