Partilhar via


Criação de classes de modelo com o LINQ to SQL (C#)

pela Microsoft

Baixar PDF

O objetivo deste tutorial é explicar um método de criação de classes de modelo para um aplicativo ASP.NET MVC. 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 ASP.NET MVC. 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 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 de aplicativos.

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 do 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 SQL Server Banco de Dados, dê a ele o nome MoviesDB.mdf e clique no botão Adicionar (consulte Figura 1).

Adicionando um novo banco de dados SQL Server

Figura 01: Adicionar 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 Servidor Explorer (consulte Figura 2).

A janela Explorer do Servidor é chamada de janela Explorer banco de dados ao usar o Visual Web Developer.

Captura de tela da janela servidor Explorer, que mostra que a pasta Tabelas está realçada na hierarquia de pastas.

Figura 02: Usando a janela servidor Explorer (Clique para exibir a imagem em tamanho real)

Precisamos adicionar uma tabela ao nosso banco de dados que represente 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 Figura 3).

Captura de tela da janela do Microsoft Visual Studio, que mostra o recurso tabela Designer.

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 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.

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 classes LINQ to SQL, dar às classes o nome Movie.dbml e clicar no botão Adicionar (consulte Figura 4).

Criando classes LINQ to SQL

Figura 04: Criando classes LINQ to SQL (Clique para exibir 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 servidor Explorer 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 5).

Usando o Object Relational Designer

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 aplicativo. Modifique a classe para que ela se pareça com a classe na Listagem 1.

Listagem 1 – Controllers\HomeController.cs

using System.Linq;
using System.Web.Mvc;
using MvcApplication1.Models;

namespace MvcApplication1.Controllers
{
     [HandleError]
     public class HomeController : Controller
     {
          public ActionResult Index()
          {
               var dataContext = new MovieDataContext();
               var movies = from m in dataContext.Movies
                    select m;
               return View(movies);
          }
     }
}

A Index() ação na Listagem 1 usa uma classe DataContext LINQ to SQL (o MovieDataContext) para representar o MoviesDB banco de dados. A MoveDataContext classe foi gerada pela Object Relational Designer do Visual Studio.

Uma consulta LINQ é executada no DataContext para recuperar todos os filmes da tblMovies tabela de banco de dados. A lista de filmes é atribuída a uma variável local chamada movies. 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 Views\Home\ pasta . 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="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="MvcApplication1.Views.Home.Index" %>
<%@ Import Namespace="MvcApplication1.Models" %>
<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">

     <ul>
          <% foreach (Movie m in (IEnumerable)ViewData.Model)

          { %>
               <li> <%= m.Title %> </li>
          <% } %>
     </ul>
</asp:Content>

Observe que a exibição de Índice modificada inclui uma <%@ import namespace %> diretiva na parte superior da exibição. Essa diretiva importa o MvcApplication1.Models namespace. Precisamos desse namespace para trabalhar com as model classes , em particular, a Movie classe - no modo de exibição.

A exibição na Listagem 2 contém um foreach loop que itera em todos os itens representados pela ViewData.Model propriedade . O valor da Title propriedade é exibido para cada movie.

Observe que o valor da ViewData.Model propriedade é convertido em um IEnumerable. Isso é necessário para percorrer o conteúdo de ViewData.Model. Outra opção aqui é criar um fortemente tipado view. Ao criar um fortemente tipado view, você converte a ViewData.Model propriedade em um tipo específico na classe code-behind de uma exibição.

Se você executar o aplicativo depois de modificar a HomeController classe 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 tblMovies banco de dados.

Para adicionar registros à tabela de tblMovies banco de dados, clique com o botão direito do tblMovies mouse na tabela de banco de dados na janela Servidor Explorer (janela banco de dados Explorer no Visual Web Developer) e selecione a opção de menu Mostrar Dados da Tabela. Você pode inserir movie registros usando a grade exibida (consulte a Figura 6).

Inserindo filmes

Figura 06: Inserindo filmes (Clique para exibir a imagem em tamanho real)

Depois de adicionar alguns registros de banco de dados à tblMovies tabela 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.

Exibindo filmes com a exibição Índice

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 MovieDataContext classe diretamente da ação do Index() controlador. 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 é nomeada IMovieRepository e representa um único método chamado ListAll().

Listagem 3 – Models\IMovieRepository.cs

using System.Collections.Generic;
namespace MvcApplication1.Models
{
     public interface IMovieRepository
     {
          IList<Movie> ListAll();
     }
}

A classe de repositório na Listagem 4 implementa a IMovieRepository interface . Observe que ele contém um método chamado ListAll() que corresponde ao método exigido pela IMovieRepository interface .

Listagem 4 – Models\MovieRepository.cs

using System.Collections.Generic;
using System.Linq;

namespace MvcApplication1.Models
{
     public class MovieRepository : IMovieRepository
     {
          private MovieDataContext _dataContext;

          public MovieRepository()
          {
                _dataContext = new MovieDataContext();
          }

          #region IMovieRepository Members

          public IList<Movie> ListAll()
          {
               var movies = from m in _dataContext.Movies
                    select m;
               return movies.ToList();
          }

          #endregion
     }
}

Por fim, a MoviesController classe na Listagem 5 usa o padrão repositório. Ele não usa mais classes LINQ to SQL diretamente.

Listagem 5 – Controllers\MoviesController.cs

using System.Web.Mvc;
using MvcApplication1.Models;

namespace MvcApplication1.Controllers
{
     public class MoviesController : Controller
     {
          private IMovieRepository _repository;

          public MoviesController() : this(new MovieRepository())
          {
          }

          public MoviesController(IMovieRepository repository)
          {
               _repository = repository;
          }

          public ActionResult Index()
          {
               return View(_repository.ListAll());
          }
     }
}

Observe que a MoviesController classe 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 e a MovieRepository passa para o segundo construtor.

O segundo construtor tem um único parâmetro: um IMovieRepository parâmetro. Esse construtor simplesmente atribui o valor do parâmetro a um campo de nível de classe chamado _repository.

A MoviesController classe 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 MoviesController classe (com exceção do primeiro construtor) interage com a IMovieRepository interface em vez da classe real MovieRepository . 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 IMovieRepository interface com uma classe que usa a tecnologia alternativa de acesso ao banco de dados. Por exemplo, você pode criar uma EntityFrameworkMovieRepository classe ou uma SubSonicMovieRepository classe. Como a classe de controlador é programada em relação à interface , você pode passar uma nova implementação de IMovieRepository para a classe de controlador e a classe continuará funcionando.

Além disso, se você quiser testar a MoviesController classe , poderá passar uma classe de repositório de filmes falso para o HomeController. Você pode implementar a IMovieRepository classe com uma classe que realmente não acessa o banco de dados, mas contém todos os métodos necessários da IMovieRepository interface. Dessa forma, você pode testar a MoviesController classe 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.