Curso Entity 
Framework - Suporte ao tipo de dados Spatial - XXVIII  
    
    
    ![]()  | 
    
 Na aula de hoje vou apresentar o suporte a dois tipos de dados Spatial : DbGeography e DbGeometry disponíveis a partir do Entity Framework 5. (aula anterior)  | 
  
| 
		      
				
				
				Chegou o Curso ASP .NET MVC 5 Vídeo Aulas (C#)  | 
  
Na aula de hoje vou escrever sobre recurso do Entity Framework, disponível a partir da versão 5, conhecido como Spatial Data ou dados geográficos.
Apenas para lembrar, a partir da versão 5 do Entity Framework, tivemos as seguintes novidades :
Spatial Data - Dados geográficos agora podem ser expostos em seu modelo usando o DbGeography e os tipos DbGeometry. Com isso podemos ter um campo do tipo DbGeography e através do namespace System.Data.Spatial manipular dados geográficos informando as coordenadas latitude e longitude;
Migrations - Este o recurso permite realizar alterações em nosso modelo de entidades e ter a atualização automática do banco de dados refletindo essas mudanças sem perder os dados;
Table Value Functions (TVF) - Este recurso permite mapear TVFs tanto para entidades como para tipos complexos no EF5; (TVFs são funções definidas pelo usuário (UDF), que vivem na base de dados alvo e cujo tipo de retorno é uma tabela.)
Enums - Permite que você tenha propriedades de enumeração - enum - em suas classes de entidade; assim o Code First já as reconhece e as implementa no database.
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.
A partir do SQL Server 2008, houve o suporte a dois tipos de dados espaciais: o tipo de dados geometry e o tipo de dados geography.
Para não ficar para trás, o Entity Framework também passou a dar suporte e trabalhar com dados espaciais/geográficos através das classes DbGeography e DbGeometry.
Essas classes se baseiam em funcionalidades especificas do banco de dados fornecidas pelo Entity Framework provider. (Nem todos os provedores dão suporte aos dados espaciais e aqueles que dão suporte podem ter pré-requisitos adicionais.)
Nesta aula 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 2013 for Windows Desktop e o Entity Framework com Code-First. (O banco de dados usado será o SQL Server instãncia LocalDB)
Vou 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).
Nota: O exemplo deste artigo mostra o Entity Framework 5 sendo usado, mas o mesmo é valido para as versões posteriores.
Usando Spatial Data com Code-First
Agora vamos instalar o Entity Framework via Nuget.
No menu TOOLS clique em Library Package Manager e a seguir em Package Manager Console;
    
    ![]()  | 
  
Se preferir pode usar o Package Manager Console digite : Install-Package EntityFramework e tecle ENTER;
    
    ![]()  | 
  
O Entity framework deverá ser instalado e adicionado ao nosso projeto conforme mostra a figura acima.
Definindo o modelo usando Code-First
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:
| 
     
	Imports 
    System.Data.Spatial Public Class Hotel Public Property HotelID As IntegerPublic Property Nome As String Public Property Cidade As String Public Property Localizacao As DbGeography End Class 
  | 
  
A propriedade Localizacao e do tipo DbGeography e para poder esse tipo temos que incluir o namespace System.Data.Spatial.
Agora temos que definir a classe que deriva de 
DbContext e expõe 
propriedades DbSet(Of TEntity)
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.
Os tipos DbContext e DbSet são definidos no 
assembly EntityFramework que foi adicionado e referenciando quando instalamos o EF via 
Nuget.
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:
| 
     
	Imports 
    System.Data.Entity Public Class HotelContext Inherits DbContextPublic Property Hoteis() As DbSet(Of Hotel) End Class 
  | 
  
Observe a referência ao namespace System.Data.Entity e que a classe HotelContext herda de DbContext.
Definindo a interface
Vamos agora definir uma interface bem simples em nosso projeto usando o formulário form1.vb e incluindo os seguintes componentes:
Disponha os controles conforme o leiaute exibido na figura abaixo:
    
    ![]()  | 
  
Defina o seguinte namespace no início do formulário form1.vb:
Imports System.Data.Spatial
Agora vamos definir o código do evento Click do botão de comando - Criar Dados com o EF5- conforme abaixo:
| 
     Private Sub btnCriarDados_Click(sender As Object, e As EventArgs) Handles btnCriarDados.Click CriarDados() End Sub 
  | 
  
O código da rotina CriarDados() é visto a seguir:
    Private Sub CriarDados()
            Using contexto = New HotelContext()
                contexto.Hoteis.Add(New Hotel() With { _
                .Nome = "Hotel Arpoador", _
                .Cidade = "Salvador", _
                .Localizacao = DbGeography.FromText("POINT(-12.983148 -38.521729)") _
            })
                contexto.Hoteis.Add(New Hotel() With { _
                .Nome = "Hotel Sereia do Mar", _
                .Cidade = "Guaruja", _
                .Localizacao = DbGeography.FromText("POINT(-23.926013 -46.300049)") _
            })
                contexto.Hoteis.Add(New Hotel() With { _
                .Nome = "Hotel Nosso Cantinho", _
                .Cidade = "Rio de Janeiro", _
                .Localizacao = DbGeography.FromText("POINT(-22.897683 -43.24585)") _
            })
                contexto.Hoteis.Add(New Hotel() With { _
                .Nome = "Hotel Candeias", _
                .Cidade = "Belo Horizonte", _
                .Localizacao = DbGeography.FromText("POINT(-19.932041 -43.970948)") _
            })
                contexto.Hoteis.Add(New Hotel() With { _
                .Nome = "Hotel America", _
                .Cidade = "Goiânia", _
                .Localizacao = DbGeography.FromText("POINT(-16.678293 -49.288331)") _
            })
                contexto.SaveChanges()
        End Using
    End Sub
    
  | 
  
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.
O método SaveChanges irá criar o banco de dados e persistir as informações na tabela Hotels.
Agora temos o código do evento Click do botão de comando - Exibir Dados Criados :
| 
    
	Private Sub 
    btnExibirDados_Click(sender As Object, 
    e As EventArgs)
    Handles 
    btnExibirDados.Click ExibirDados() End Sub  | 
  
O código da rotina ExibirDados() é dado a seguir:
      Private Sub ExibirDados()
        Using contexto = New HotelContext()
            Dim locais = From loc In contexto.Hoteis
                             Select loc
                lsbDados.Items.Clear()
                For Each hot In locais
                lsbDados.Items.Add(hot.Nome + " - " + hot.Cidade + " - " + hot.Localizacao.ToString())
            Next
        End Using
    End Sub
    
  | 
  
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:
     Private Sub btnLocalizar_Click(sender As Object, e As EventArgs) Handles btnLocalizar.Click
        Using contexto = New HotelContext
            Dim coordenadas As String = txtLocalizacao.Text
            Dim minhaLocalizacao = DbGeography.FromText("POINT(" + coordenadas + ")") 'Brasilia
                Dim hotel = (From ht In contexto.Hoteis Order By
                              ht.Localizacao.Distance(minhaLocalizacao) _
                              Select ht).FirstOrDefault
                lblResposta.Text = "O hotel mais perto desta localização é : " + vbCrLf + hotel.Nome + vbCrLf + hotel.Cidade + vbCrLf + 
hotel.Localizacao.Latitude.ToString + "-" + hotel.Localizacao.Longitude.ToString
        End Using
    End Sub
    
  | 
  
Note que estamos usando 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.
Nota: Lembre que a classe DbGeography representa dados em um sistema de coordenadas geodésicas
    
	
    ![]()  | 
  
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...
Pegue o projeto completo aqui:
 
EF5_SpatialData.zip (sem a referência ao EF5)
Na próxima aula vamos tratar do recurso Table-Valued Function no Entity Framework.
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.
| 
    
    Veja os 
    Destaques e novidades do SUPER DVD Visual Basic 
(sempre atualizado) : clique e confira ! 
 Quer migrar para o VB .NET ? 
 Quer aprender C# ?? 
 Quer aprender os conceitos da Programação Orientada a objetos ? Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ? Quer aprender a criar aplicações Web Dinâmicas usando a ASP .NET MVC 5 ? 
  | 
  
      Gostou ?
 
Compartilhe no Facebook 
  
 
 
Compartilhe no Twitter
 
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#