Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
por Microsoft
El objetivo de este tutorial es explicar un método para crear clases de modelo para una aplicación ASP.NET MVC. En este tutorial, aprenderá a crear clases de modelo y a realizar el acceso a la base de datos aprovechando Microsoft LINQ to SQL.
El objetivo de este tutorial es explicar un método para crear clases de modelo para una aplicación ASP.NET MVC. En este tutorial, aprenderá a crear clases de modelo y a realizar el acceso a la base de datos aprovechando Microsoft LINQ to SQL.
En este tutorial, se crea una aplicación básica de base de datos Movie. Comenzamos creando la aplicación de base de datos Movie de la manera más rápida y sencilla posible. Realizamos todo el acceso a los datos directamente desde nuestras acciones del controlador.
A continuación, aprenderemos a usar el patrón Repository. El uso del patrón Repository requiere un poco más de trabajo. Sin embargo, la ventaja de adoptar este patrón es que permite compilar aplicaciones adaptables al cambio y que se pueden probar fácilmente.
¿Qué es una clase Model?
Un modelo MVC contiene toda la lógica de la aplicación que no está incluida en una vista o un controlador. En concreto, contiene toda la lógica de acceso a datos y de negocio de la aplicación.
Para implementar la lógica de acceso a datos puede usar una variedad de tecnologías diferentes. Por ejemplo, puede crear las clases de acceso a datos mediante las clases Microsoft Entity Framework, NHibernate, Subsonic o ADO.NET.
En este tutorial, usaremos LINQ to SQL para consultar y actualizar la base de datos. LINQ to SQL proporciona un método muy fácil de interactuar con una base de datos de Microsoft SQL Server. Sin embargo, es importante comprender que el marco ASP.NET MVC no está vinculado a LINQ to SQL de ninguna manera. ASP.NET MVC es compatible con cualquier tecnología de acceso a datos.
Creación de una base de datos Movie
En este tutorial, para ilustrar cómo se crean clases de modelo, creamos una sencilla aplicación de base de datos Movie. El primer paso es crear una nueva aplicación. Haga clic con el botón derecho en la carpeta App_Data de la ventana Explorador de soluciones y seleccione la opción de menú Agregar, Nuevo elemento. Seleccione la plantilla SQL Server Database, asígnele el nombre MoviesDB.mdf y haga clic en el botón Agregar (consulte la figura 1).
Figura 01: Incorporación de una nueva base de datos de SQL Server (haga clic para ver la imagen a tamaño completo)
Después de crear la nueva base de datos, haga doble clic en el archivo MoviesDB.mdf en la carpeta App_Data para abrirla. Al hacer doble clic en el archivo MoviesDB.mdf, se abre la ventana Explorador de servidores (consulte la figura 2).
La ventana Explorador de servidores se denomina ventana Explorador de bases de datos cuando se usa Visual Web Developer.
Figura 02: Uso de la ventana Explorador de servidores (haga clic para ver la imagen a tamaño completo)
Necesitamos agregar una tabla a nuestra base de datos que represente nuestras películas. Haga clic con el botón derecho en la carpeta Tablas y seleccione la opción de menú Agregar nueva tabla. Al seleccionar esta opción de menú, se abre el Diseñador de tablas (consulte la figura 3).
Figura 03: Diseñador de tablas (haga clic para ver la imagen a tamaño completo)
Es necesario agregar las columnas siguientes a la tabla de base de datos:
Nombre de la columna | Tipo de datos | Permitir valores NULL |
---|---|---|
Identificador | Int | False |
Título | Nvarchar(200) | False |
Director | Nvarchar(50) | False |
Debe hacer dos cosas especiales en la columna Id. En primer lugar, marque la columna Id como columna de clave principal seleccionando la columna en el Diseñador de tablas y haciendo clic en el icono de una clave. LINQ to SQL necesita que se especifiquen las columnas de clave principal al realizar inserciones o actualizaciones en la base de datos.
A continuación, marque la columna Id como columna Identity mediante la asignación del valor Sí a la propiedad Is Identity (consulte la figura 3). Una columna Identity es la que se asigna automáticamente a un nuevo número cada vez que se agrega una nueva fila de datos a una tabla.
Después de realizar estos cambios, guarde la tabla con el nombre tblMovie. Para guardar la tabla, haga clic en el botón Guardar.
Creación de clases LINQ to SQL
Nuestro modelo MVC contendrá clases LINQ to SQL que representan la tabla de base de datos tblMovie. La manera más fácil de crear estas clases LINQ to SQL es hacer clic con el botón derecho en la carpeta Modelos, seleccionar Agregar, Nuevo elemento, seleccionar la plantilla LINQ to SQL Classes, asignarle el nombre Movie.dbml y hacer clic en el botón Agregar (consulte la figura 4).
Figura 04: Creación de clases LINQ to SQL (haga clic para ver la imagen a tamaño completo)
Inmediatamente después de crear LINQ to SQL Classes de Movie, Object Relational Designer aparece. Puede arrastrar tablas de base de datos desde la ventana Explorador de servidores a Object Relational Designer para crear LINQ to SQL Classes que representen tablas de base de datos concretas. Es necesario agregar la tabla de base de datos tblMovie a Object Relational Designer (consulte la figura 4).
Figura 05: Uso de Object Relational Designer (haga clic para ver la imagen a tamaño completo)
De forma predeterminada, Object Relational Designer crea una clase con el mismo nombre que la tabla de base de datos que arrastra al Diseñador. Sin embargo, no queremos llamar a nuestra clase tblMovie. Por lo tanto, haga clic en el nombre de la clase en el Diseñador y cambie el nombre de la clase a Movie.
Por último, recuerde hacer clic en el botón Guardar (la imagen del disquete) para guardar la plantilla LINQ to SQL Classes. De lo contrario, Object Relational Designer no generará las clases LINQ to SQL.
Uso de LINQ to SQL en una acción del controlador
Ahora que tenemos nuestras clases de LINQ to SQL, podemos usarlas para recuperar datos de la base de datos. En esta sección, aprenderá a usar las clases LINQ to SQL directamente dentro de una acción de controlador. Mostraremos la lista de películas de la tabla de base de datos tblMovies en una vista MVC.
En primer lugar, es necesario modificar la clase HomeController. Esta clase se encuentra en la carpeta Controllers de la aplicación. Modifique la clase para que tenga el aspecto de la clase de la lista 1.
Lista 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
La acción Index() de la lista 1 usa una clase DataContext de LINQ to SQL (MovieDataContext) para representar la base de datos MoviesDB. Object Relational Designer de Visual Studio generó la clase MoveDataContext.
Se realiza una consulta LINQ en DataContext para recuperar todas las películas de la tabla de base de datos tblMovies. La lista de películas se asigna a una variable local denominada movies. Por último, la lista de películas se pasa a la vista mediante los datos de la vista.
Para mostrar las películas, es necesario modificar la vista Index. La vista Index se encuentra en la carpeta Views\Home\. Actualice la vista Index para que tenga un aspecto similar a la vista de la lista 2.
Lista 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 la vista Index modificada incluye una directiva <%@ import namespace %> en la parte superior. Esta directiva importa el espacio de nombres MvcApplication1. Necesitamos este espacio de nombres para trabajar con las clases de modelo (en particular, la clase Movie) en la vista.
La vista de la lista 2 contiene un bucle For Each que recorre en iteración todos los elementos representados por la propiedad ViewData.Model. El valor de la propiedad Title se muestra para cada película.
Observe que el valor de la propiedad ViewData.Model se convierte en IEnumerable. Esto es necesario para recorrer en bucle el contenido de ViewData.Model. Otra opción aquí es crear una vista fuertemente tipada. Cuando se crea una vista fuertemente tipada, se convierte la propiedad ViewData.Model en un tipo determinado en la clase de código subyacente de una vista.
Si ejecuta la aplicación después de modificar la clase HomeController y la vista Index, obtendrá una página en blanco. Obtendrá una página en blanco porque no hay ningún registro de película en la tabla de base de datos tblMovies.
Para agregar registros a la tabla de base de datos tblMovies, haga clic con el botón derecho en la tabla de base de datos tblMovies en la ventana Explorador de servidores (ventana Explorador de bases de datos en Visual Web Developer) y seleccione la opción de menú Mostrar datos de tabla. Puede insertar registros de películas mediante la cuadrícula que aparece (consulte la figura 5).
Figura 06: Inserción de películas(haga clic para ver la imagen a tamaño completo)
Después de agregar algunos registros de base de datos a la tabla tblMovies y ejecutar la aplicación, verá la página de la figura 7. Todos los registros de la base de datos de películas se muestran en una lista con viñetas.
Figura 07: Visualización de las películas con la vista Index (haga clic para ver la imagen a tamaño completo)
Uso del patrón Repository
En la sección anterior, usamos clases LINQ to SQL directamente dentro de una acción de controlador. Usamos la clase MovieDataContext directamente desde la acción del controlador Index(). No hay nada malo en hacerlo en el caso de una aplicación sencilla. Sin embargo, trabajar directamente con LINQ to SQL en una clase de controlador implica problemas al compilar una aplicación más compleja.
El uso de LINQ to SQL en una clase de controlador dificulta el cambio de tecnologías de acceso a datos en el futuro. Por ejemplo, puede decidir cambiar de Microsoft LINQ to SQL a Microsoft Entity Framework como tecnología de acceso a los datos. En ese caso, tendría que volver a escribir todos los controladores que tengan acceso a la base de datos dentro de la aplicación.
El uso de LINQ to SQL dentro de una clase de controlador también dificulta la compilación de pruebas unitarias para la aplicación. Normalmente, no se quiere interactuar con una base de datos al realizar pruebas unitarias. Las pruebas unitarias sirven para probar la lógica de la aplicación y no el servidor de bases de datos.
Para compilar una aplicación de MVC más adaptable al cambio futuro y que se pueda probar más fácilmente, considere el patrón Repository. Al usar el patrón Repository, se crea una clase de repositorio independiente que contiene toda la lógica de acceso a la base de datos.
Al crear la clase Repository, se crea una interfaz que representa todos los métodos que esta usa. Dentro de los controladores, escribirá el código en la interfaz en lugar de en el repositorio. De este modo, puede implementar el repositorio mediante diferentes tecnologías de acceso a datos en el futuro.
La interfaz de la lista 3 se denomina IMovieRepository y representa un único método denominado ListAll().
Lista 3 – Models\IMovieRepository.vb
Public Interface IMovieRepository
Function ListAll() As IList(Of Movie)
End Interface
La clase Repository de la lista 4 implementa la interfaz IMovieRepository. Observe que contiene un método denominado ListAll() que corresponde al método que requiere la interfaz IMovieRepository.
Lista 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 último, la clase MoviesController de la lista 5 usa el patrón Repository. Ya no usa clases LINQ to SQL directamente.
Lista 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 la clase MoviesController de la lista 5 tiene dos constructores. Al primer constructor, sin parámetros, se le llama cuando se ejecuta la aplicación. Este constructor crea una instancia de la clase MovieRepository y la pasa al segundo constructor.
El segundo constructor tiene un único parámetro: IMovieRepository. Este constructor simplemente asigna el valor del parámetro a un campo de nivel de clase denominado _repository.
La clase MoviesController aprovecha un patrón de diseño de software denominado patrón de inserción de dependencias. En concreto, usa algo denominado Inserción de dependencias de constructor. Para más información sobre este patrón, lea el siguiente artículo de Martin Fowler:
http://martinfowler.com/articles/injection.html
Observe que todo el código de la clase MoviesController (con la excepción del primer constructor) interactúa con la interfaz IMovieRepository en lugar de la clase MovieRepository real. El código interactúa con una interfaz abstracta en lugar de una implementación concreta de la interfaz.
Si desea modificar la tecnología de acceso a datos que usa la aplicación, simplemente implemente la interfaz IMovieRepository con una clase que use la tecnología alternativa de acceso a bases de datos. Por ejemplo, podría crear una clase EntityFrameworkMovieRepository o SubSonicMovieRepository. Dado que la clase de controlador está programada en la interfaz, puede pasar una nueva implementación de IMovieRepository a la clase de controlador y la clase seguiría funcionando.
Además, si desea probar la clase MoviesController, puede pasar una clase de repositorio de películas falsa a MoviesController. Puede implementar la clase IMovieRepository con una clase que realmente no tiene acceso a la base de datos, pero contiene todos los métodos necesarios de la interfaz IMovieRepository. De este modo, realiza pruebas unitarias de la clase MoviesController sin acceder a una base de datos real.
Resumen
El objetivo de este tutorial era demostrar cómo se crean clases de modelo de MVC aprovechando Microsoft LINQ to SQL. Hemos examinado dos estrategias para mostrar datos de base de datos en una aplicación ASP.NET MVC. En primer lugar, creamos clases LINQ to SQL y las usamos directamente dentro de una acción de controlador. El uso de clases LINQ to SQL dentro de un controlador permite mostrar datos de base de datos de forma rápida y sencilla en una aplicación MVC.
A continuación, hemos explorado una ruta de acceso un poco más difícil, pero definitivamente más virtuosa para mostrar los datos de la base de datos. Aprovechamos el patrón Repository y colocamos toda la lógica de acceso a la base de datos en una clase de repositorio independiente. En nuestro controlador, hemos escrito todo el código en una interfaz en lugar de en una clase concreta. La ventaja del patrón Repository es que nos permite cambiar fácilmente las tecnologías de acceso a bases de datos en el futuro y probar fácilmente nuestras clases de controlador.