Criação de classes de modelo com o LINQ to SQL (VB)
pela Microsoft
O objetivo deste tutorial é explicar um método de criação de classes de modelo para um aplicativo MVC ASP.NET. Neste tutorial, você aprenderá a criar classes de modelo e a executar o acesso ao banco de dados aproveitando o Microsoft LINQ to SQL.
O objetivo deste tutorial é explicar um método de criação de classes de modelo para um aplicativo MVC ASP.NET. Neste tutorial, você aprenderá a criar classes de modelo e a executar o acesso ao banco de dados aproveitando o Microsoft LINQ to SQL.
Neste tutorial, criamos um aplicativo de banco de dados de filme básico. Começamos criando o aplicativo de banco de dados Movie da maneira mais rápida e fácil possível. Executamos todo o acesso a dados diretamente de nossas ações do controlador.
Em seguida, você aprenderá a usar o padrão repositório. Usar o padrão de Repositório requer um pouco mais de trabalho. No entanto, a vantagem de adotar esse padrão é que ele permite que você crie aplicativos adaptáveis para alterar e que podem ser facilmente testados.
O que é uma classe de modelo?
Um modelo MVC contém toda a lógica do aplicativo que não está contida em uma exibição MVC ou controlador MVC. Em particular, um modelo MVC contém toda a lógica de acesso a dados e negócios do aplicativo.
Você pode usar uma variedade de tecnologias diferentes para implementar sua lógica de acesso a dados. Por exemplo, você pode criar suas classes de acesso a dados usando as classes microsoft Entity Framework, NHibernate, Subsonic ou ADO.NET.
Neste tutorial, uso LINQ to SQL para consultar e atualizar o banco de dados. LINQ to SQL fornece um método muito fácil de interagir com um banco de dados do Microsoft SQL Server. No entanto, é importante entender que a estrutura ASP.NET MVC não está vinculada a LINQ to SQL de forma alguma. ASP.NET MVC é compatível com qualquer tecnologia de acesso a dados.
Criar um banco de dados de filme
Neste tutorial, para ilustrar como você pode criar classes de modelo, criamos um aplicativo de banco de dados Movie simples. A primeira etapa é criar um novo banco de dados. Clique com o botão direito do mouse na pasta App_Data na janela Gerenciador de Soluções e selecione a opção de menu Adicionar, Novo Item. Selecione o modelo banco de dados SQL Server, dê a ele o nome MoviesDB.mdf e clique no botão Adicionar (consulte a Figura 1).
Figura 01: Adicionando um novo banco de dados SQL Server (clique para exibir a imagem em tamanho real)
Depois de criar o novo banco de dados, você pode abrir o banco de dados clicando duas vezes no arquivo MoviesDB.mdf na pasta App_Data. Clicar duas vezes no arquivo MoviesDB.mdf abre a janela Explorer servidor (consulte a Figura 2).
A janela Explorer do Servidor é chamada de janela Explorer banco de dados ao usar o Visual Web Developer.
Figura 02: Usando a janela Explorer servidor (clique para exibir a imagem em tamanho real)
Precisamos adicionar uma tabela ao nosso banco de dados que representa nossos filmes. Clique com o botão direito do mouse na pasta Tabelas e selecione a opção de menu Adicionar Nova Tabela. Selecionar essa opção de menu abre o Designer tabela (consulte a Figura 3).
Figura 03: a tabela Designer (clique para exibir a imagem em tamanho real)
Precisamos adicionar as seguintes colunas à nossa tabela de banco de dados:
Nome da Coluna | Tipo de Dados | Permitir Nulos |
---|---|---|
ID | int | Falso |
Title | Nvarchar(200) | Falso |
Diretor | Nvarchar(50) | Falso |
Você precisa fazer duas coisas especiais para a coluna ID. Primeiro, você precisa marcar a coluna ID como uma coluna de chave primária selecionando a coluna no Designer tabela e clicando no ícone de uma chave. LINQ to SQL exige que você especifique suas colunas de chave primária ao executar inserções ou atualizações no banco de dados.
Em seguida, você precisa marcar a coluna Id como uma coluna Identity atribuindo o valor Sim à propriedade Is Identity (consulte a Figura 3). Uma coluna Identity é uma coluna que recebe um novo número automaticamente sempre que você adiciona uma nova linha de dados a uma tabela.
Depois de fazer essas alterações, salve a tabela com o nome tblMovie. Você pode salvar a tabela clicando no botão Salvar.
Criar classes LINQ to SQL
Nosso modelo MVC conterá LINQ to SQL classes que representam a tabela de banco de dados tblMovie. A maneira mais fácil de criar essas classes LINQ to SQL é clicar com o botão direito do mouse na pasta Modelos, selecionar Adicionar, Novo Item, selecionar o modelo LINQ to SQL Classes, dar às classes o nome Movie.dbml e clicar no botão Adicionar (consulte a Figura 4).
Figura 04: Criando classes LINQ to SQL (clique para exibir a imagem em tamanho real)
Imediatamente após criar as Classes de LINQ to SQL de Filme, a Object Relational Designer será exibida. Você pode arrastar tabelas de banco de dados da janela Explorer servidor para o Object Relational Designer para criar classes LINQ to SQL que representam tabelas de banco de dados específicas. Precisamos adicionar a tabela de banco de dados tblMovie à Object Relational Designer (consulte a Figura 4).
Figura 05: Usando o Object Relational Designer (clique para exibir a imagem em tamanho real)
Por padrão, o Object Relational Designer cria uma classe com o mesmo nome que a tabela de banco de dados que você arrasta para o Designer. No entanto, não queremos chamar nossa classe tblMovie. Portanto, clique no nome da classe no Designer e altere o nome da classe para Movie.
Por fim, lembre-se de clicar no botão Salvar (a imagem do disquete) para salvar as classes LINQ to SQL. Caso contrário, as classes LINQ to SQL não serão geradas pelo Object Relational Designer.
Usando LINQ to SQL em uma ação do controlador
Agora que temos nossas classes LINQ to SQL, podemos usar essas classes para recuperar dados do banco de dados. Nesta seção, você aprenderá a usar classes LINQ to SQL diretamente dentro de uma ação do controlador. Exibiremos a lista de filmes da tabela de banco de dados tblMovies em um modo de exibição MVC.
Primeiro, precisamos modificar a classe HomeController. Essa classe pode ser encontrada na pasta Controladores do seu aplicativo. Modifique a classe para que ela se pareça com a classe na Listagem 1.
Listagem 1 – Controllers\HomeController.vb
<HandleError()> _
Public Class HomeController
Inherits System.Web.Mvc.Controller
Function Index()
Dim dataContext As New MovieDataContext()
Dim movies = From m In dataContext.Movies _
Select m
return View(movies)
End Function
End Class
A ação Index() na Listagem 1 usa um LINQ to SQL classe DataContext (o MovieDataContext) para representar o banco de dados MoviesDB. A classe MoveDataContext foi gerada pela Object Relational Designer do Visual Studio.
Uma consulta LINQ é executada no DataContext para recuperar todos os filmes da tabela de banco de dados tblMovies. A lista de filmes é atribuída a uma variável local chamada filmes. Por fim, a lista de filmes é passada para a exibição por meio de dados de exibição.
Para mostrar os filmes, precisamos modificar a exibição Índice. Você pode encontrar a exibição Índice na pasta Views\Home\. Atualize a exibição Índice para que ela se pareça com a exibição na Listagem 2.
Listagem 2 – Views\Home\Index.aspx
<%@ Page Language="VB" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="false" CodeBehind="Index.aspx.vb" Inherits="MvcApplication1.Index" %>
<%@ Import Namespace="MvcApplication1" %>
<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
<ul>
<% For Each m As Movie In ViewData.Model%>
<li><%= m.Title %></li>
<% Next%>
</ul>
</asp:Content>
Observe que a exibição index modificada inclui uma <diretiva %@ import namespace %> na parte superior da exibição. Essa diretiva importa o namespace MvcApplication1. Precisamos desse namespace para trabalhar com as classes de modelo – em particular, a classe Movie – no modo de exibição.
O modo de exibição na Listagem 2 contém um loop For Each que itera em todos os itens representados pela propriedade ViewData.Model. O valor da propriedade Title é exibido para cada filme.
Observe que o valor da propriedade ViewData.Model é convertido em um IEnumerable. Isso é necessário para percorrer o conteúdo de ViewData.Model. Outra opção aqui é criar uma exibição fortemente tipada. Ao criar uma exibição fortemente tipada, você converte a propriedade ViewData.Model em um tipo específico na classe code-behind de uma exibição.
Se você executar o aplicativo depois de modificar a classe HomeController e a exibição Índice, receberá uma página em branco. Você receberá uma página em branco porque não há registros de filme na tabela de banco de dados tblMovies.
Para adicionar registros à tabela de banco de dados tblMovies, clique com o botão direito do mouse na tabela de banco de dados tblMovies na janela servidor Explorer (janela Explorer banco de dados no Visual Web Developer) e selecione a opção de menu Mostrar Dados da Tabela. Você pode inserir registros de filme usando a grade exibida (consulte a Figura 5).
Figura 06: Inserindo filmes (Clique para exibir a imagem em tamanho real)
Depois de adicionar alguns registros de banco de dados à tabela tblMovies e executar o aplicativo, você verá a página na Figura 7. Todos os registros do banco de dados de filmes são exibidos em uma lista com marcadores.
Figura 07: Exibindo filmes com o modo de exibição Índice (clique para exibir a imagem em tamanho real)
Usando o padrão de repositório
Na seção anterior, usamos LINQ to SQL classes diretamente dentro de uma ação do controlador. Usamos a classe MovieDataContext diretamente da ação do controlador Index(). Não há nada de errado em fazer isso no caso de um aplicativo simples. No entanto, trabalhar diretamente com LINQ to SQL em uma classe de controlador cria problemas quando você precisa criar um aplicativo mais complexo.
Usar LINQ to SQL em uma classe de controlador dificulta a troca de tecnologias de acesso a dados no futuro. Por exemplo, você pode decidir mudar de usar o Microsoft LINQ to SQL para usar o Microsoft Entity Framework como sua tecnologia de acesso a dados. Nesse caso, você precisaria reescrever todos os controladores que acessam o banco de dados em seu aplicativo.
Usar LINQ to SQL em uma classe de controlador também dificulta a criação de testes de unidade para seu aplicativo. Normalmente, você não deseja interagir com um banco de dados ao executar testes de unidade. Você deseja usar os testes de unidade para testar a lógica do aplicativo e não o servidor de banco de dados.
Para criar um aplicativo MVC mais adaptável a alterações futuras e que possa ser testado com mais facilidade, você deve considerar o uso do padrão repositório. Ao usar o padrão repositório, você cria uma classe de repositório separada que contém toda a lógica de acesso ao banco de dados.
Ao criar a classe de repositório, você cria uma interface que representa todos os métodos usados pela classe de repositório. Em seus controladores, você escreve seu código na interface em vez do repositório. Dessa forma, você pode implementar o repositório usando diferentes tecnologias de acesso a dados no futuro.
A interface na Listagem 3 é denominada IMovieRepository e representa um único método chamado ListAll().
Listagem 3 – Models\IMovieRepository.vb
Public Interface IMovieRepository
Function ListAll() As IList(Of Movie)
End Interface
A classe de repositório na Listagem 4 implementa a interface IMovieRepository. Observe que ele contém um método chamado ListAll() que corresponde ao método exigido pela interface IMovieRepository.
Listagem 4 – Models\MovieRepository.vb
Public Class MovieRepository Implements IMovieRepository
Private _dataContext As MovieDataContext
Public Sub New()
_dataContext = New MovieDataContext()
End Sub
Public Function ListAll() As IList(Of Movie) Implements IMovieRepository.ListAll
Dim movies = From m In _dataContext.Movies _
Select m
Return movies.ToList()
End Function
End Class
Por fim, a classe MoviesController na Listagem 5 usa o padrão repositório. Ele não usa mais classes LINQ to SQL diretamente.
Listagem 5 – Controllers\MoviesController.vb
using System.Web.Mvc;
using MvcApplication1.Models;
namespace MvcApplication1.Controllers
{
Public Class MoviesController
Inherits System.Web.Mvc.Controller
Private _repository As IMovieRepository
Sub New()
Me.New(New MovieRepository())
End Sub
Sub New(ByVal repository As IMovieRepository)
_repository = repository
End Sub
Function Index()
Return View(_repository.ListAll())
End Function
End Class
}
Observe que a classe MoviesController na Listagem 5 tem dois construtores. O primeiro construtor, o construtor sem parâmetros, é chamado quando o aplicativo está em execução. Esse construtor cria uma instância da classe MovieRepository e a passa para o segundo construtor.
O segundo construtor tem um único parâmetro: um parâmetro IMovieRepository. Esse construtor simplesmente atribui o valor do parâmetro a um campo de nível de classe chamado _repository.
A classe MoviesController está aproveitando um padrão de design de software chamado padrão de Injeção de Dependência. Em particular, ele está usando algo chamado Injeção de Dependência do Construtor. Você pode ler mais sobre esse padrão lendo o seguinte artigo de Martin Fowler:
http://martinfowler.com/articles/injection.html
Observe que todo o código na classe MoviesController (com exceção do primeiro construtor) interage com a interface IMovieRepository em vez da classe MovieRepository real. O código interage com uma interface abstrata em vez de uma implementação concreta da interface.
Se você quiser modificar a tecnologia de acesso a dados usada pelo aplicativo, poderá simplesmente implementar a interface IMovieRepository com uma classe que usa a tecnologia alternativa de acesso ao banco de dados. Por exemplo, você pode criar uma classe EntityFrameworkMovieRepository ou uma classe SubSonicMovieRepository. Como a classe de controlador é programada em relação à interface , você pode passar uma nova implementação de IMovieRepository para a classe do controlador e a classe continuará funcionando.
Além disso, se você quiser testar a classe MoviesController, poderá passar uma classe de repositório de filmes falso para o MoviesController. Você pode implementar a classe IMovieRepository com uma classe que realmente não acessa o banco de dados, mas contém todos os métodos necessários da interface IMovieRepository. Dessa forma, você pode testar unitário a classe MoviesController sem realmente acessar um banco de dados real.
Resumo
O objetivo deste tutorial era demonstrar como você pode criar classes de modelo MVC aproveitando o Microsoft LINQ to SQL. Examinamos duas estratégias para exibir dados de banco de dados em um aplicativo MVC ASP.NET. Primeiro, criamos classes LINQ to SQL e usamos as classes diretamente dentro de uma ação do controlador. O uso de classes LINQ to SQL em um controlador permite que você exiba dados de banco de dados de forma rápida e fácil em um aplicativo MVC.
Em seguida, exploramos um caminho um pouco mais difícil, mas definitivamente mais virtuoso, para exibir dados de banco de dados. Aproveitamos o padrão de Repositório e colocamos toda a nossa lógica de acesso ao banco de dados em uma classe de repositório separada. Em nosso controlador, escrevemos todo o código em relação a uma interface em vez de uma classe concreta. A vantagem do padrão de Repositório é que ele nos permite alterar facilmente as tecnologias de acesso ao banco de dados no futuro e nos permite testar facilmente nossas classes de controlador.