Hoje eu vou escrever sobre um novo recurso do Entity Framework, disponível a partir da versão 5, (a versão 6.0 já esta em beta) conhecido como Spatial Data ou Dados geográficos.
A versão 5 do Entity Framework, a partir de agora citada apenas como EF5, além de um novo modelo de mapeamento Code First (Sem Designer nem XML), nova APi DBContext e melhorias no desempenho trouxe as seguintes novidades:
O Code First agora detecta se você tem o LocalDB ou o SQL Express disponível para criar novas bases de dados.O Visual Studio 2012 inclui o LocalDB, enquanto Visual Studio 2010 inclui o SQL Express.
Outro detalhe importante: Agora o Entity Framework é Open Source, e, tem o código aberto e esta esperando pela nossa contribuição... (ASP .NET MVC, ASP .NET Web API e Razor também são projetos Open Source...)
Os dados espaciais representam informações sobre o local físico e a forma de objetos geométricos. Esses objetos podem ser locais de pontos ou objetos mais complexos como países, estradas ou lagos.
O SQL Server suporta dois tipos de dados espaciais: o tipo de dados geometry e o tipo de dados geography.
Neste artigo eu vou mostrar um exemplo simples e prático de utilização dos dados geográficos com Code-First em uma aplicação VB .NET usando o Visual Studio Express 2012 for Windows Desktop e o Entity Framework com Code-First. (O banco de dados usado será o LocalDB)
Iremos criar uma aplicação onde iremos gerar um banco de dados com informações de alguns hotéis como nome, cidade e localização geográfica usando as coordenadas de latitude e longitude (obtidas do Google Maps).
No painel esquerdo, clique em Visual Basic e em seguida selecione o modelo Windows Forms Application;
O Entity framework 5 deverá ser instalado e adicionado ao nosso projeto conforme mostra a figura acima.
Ao utilizar o modelo de desenvolvimento Code-First geralmente começamos definindo as classes do nosso modelo conceitual ou seja do nosso domínio. Para o exemplo do artigo irei definir a classe Hotel com as propriedades : HotelID, Nome, Cidade e Localizacao :
Clique no menu PROJECT e a seguir em Add Class e informe o nome Hotel.vb a seguir defina o código abaixo para a classe Hotel:
As propriedades DbSet(Of TEntity) permitem que o contexto reconheça quais tipos desejamos incluir em nosso modelo.
Uma instância do tipo derivado DbContext gerencia os objetos de entidade durante o tempo de execução, o qual inclui popular os objetos com dados de um banco de dados, controlar as alterações, e persistir os dados no banco de dados.
Clique no menu PROJECT e a seguir em Add Class e informe o nome HotelContext.vb a seguir defina o código abaixo para a classe HotelContext:
Vamos agora definir uma interface bem simples em nosso projeto usando o formulário form1.vb e incluindo os seguintes componentes:
Agora vamos definir o código do evento Click do botão de comando - Criar Dados com o EF5- conforme abaixo:
Neste código estou incluindo informações para 5 hotéis na tabela Hotels. Observe que o tipo de dado Localizacao é do tipo DbGeography e esta sendo informando com as coordenadas, latitude e longitude, que representa a localização do hotel no Google Maps.
No código acima estou selecionando os dados da entidade Hotels exibindo-as em um ListBox usando uma consulta LINQ.
Para localizar um hotel mais próximo da minha localização com base nas coordenadas (latitude/longitude) temos o código abaixo no evento Click do botão : Encontrar Hotel mais perto:
            lblResposta.Text = "O hotel mais perto desta localização é : " + vbCrLf + hotel.Nome + vbCrLf + hotel.Cidade + vbCrLf + 
Note que estamos o método Distance da classe DbGeography para calcular a distância entre os pontos mais próximos das coordenadas da minha localização. No resultado estou usando as propriedades Latitude e Longitude da mesma classe para exibir os respectivos valores das coordenadas.
No menu VIEW clique em DataBase Explorer e a seguir clique com o botão direito sobre Data Connections e selecione Add Connection;
Informe o nome do servidor de banco de dados como LocalDB\v11.0 e abra a caixa dropdownlist em Select ou enter a database name;
Perceba que entre os bancos de dados listados podemos identificar um contendo o nome da nossa solução e do nosso contexto. Esse é o banco de dados que foi criado automaticamente pelo Code-First:
Observe que o banco de dados foi criado com o nome EF5_SpatialData.HotelContext que é o formato padrão de nomes usado : Nome da Solucao+Nome do Contexto
Selecionando o banco de dados e expandindo os objetos Tables vemos a tabela Hotels; clicando bom o botão direito do mouse sobre ela e selecionando Show Table Data vermos os dados que foram persistidos pela Code-First.
Conferimos desta a forma a utilização do novo recurso Spatial Data no Entity Framework 5. Pense nas possibilidades...
Mar 1:5 E saíam a ter com ele toda a terra da Judéia, e todos os moradores de Jerusalém; e eram por ele batizados no rio Jordão, confessando os seus pecados.
Mar 1:6 Ora, João usava uma veste de pelos de camelo, e um cinto de couro em torno de seus lombos, e comia gafanhotos e mel silvestre.
Mar 1:7 E pregava, dizendo: Após mim vem aquele que é mais poderoso do que eu, de quem não sou digno de, inclinando-me, desatar a correia das alparcas.
Se você não conhece os conceitos básicos sobre LINQ leia meus artigos citados nas referências. Neste artigo eu vou falar um pouco sobre LINQ Queries e os estilos para escrever consultas LINQ.
Esses métodos de extensão adicionam métodos adicionais para instâncias de IEnumerable<TSource>, e , isso significa que qualquer instância de uma classe que implementa essa interface pode usar esses métodos de extensão.
Nesta consulta temos uma cadeia de operadores de consulta. Cada operador funciona na sequência fornecida pelo operador de consulta anterior.
O método Select emite uma seqüência onde cada elemento de entrada é transformado com uma dada expressão lambda (x.Nome(), neste caso).
Observe que a entrada inicial, representada pela variável ingredientes, é do tipo IEnumerable<Ingrediente>, enquanto a seqüência de saída (representada pela variável consultaIngredientesComMaisCalorias) , é um tipo diferente; é um IEnumerable <string>.
Neste exemplo, a cadeia de operadores está trabalhando com uma seqüência de elementos ingredientes até o operador Select transformar cada elemento na sequência; cada objeto de ingrediente é transformado em uma string simples.
Essa transformação é chamada de projeção: Os elementos de entrada são projetados em elementos de saída transformados.
A expressão lambda fornecida ao operador de consulta Select decide o 'formato' dos elementos na sequência de saída necessário.
A expressão lambda x => x.Nome está dizendo para o operador Select que "para cada elemento ingrediente, emita um elemento de string com o valor do Nome da propriedade do Ingrediente de entrada."