Parte 4: modelos y acceso a datos

por Jon Galloway

El almacén de música de MVC es una aplicación de tutorial que presenta y explica paso a paso cómo usar ASP.NET MVC y Visual Studio para el desarrollo web.

MVC Music Store es una implementación ligera de almacén de ejemplo que vende álbumes musicales en línea e implementa la funcionalidad básica de administración de sitios, Inicio de sesión de usuario y carro de la compra.

En esta serie de tutoriales se detallan todos los pasos realizados para compilar la aplicación de ejemplo ASP.NET MVC Music Store. La parte 4 cubre los modelos y el acceso a los datos.

Hasta ahora, acabamos de pasar "datos ficticios" de nuestros controladores a nuestras plantillas de vista. Ahora estamos preparados para enlazar una base de datos real. En este tutorial, vamos a tratar cómo usar SQL Server Compact Edition (a menudo denominado SQL CE) como nuestro motor de base de datos. SQL CE es una base de datos gratuita, incrustada y basada en archivos que no requiere ninguna instalación o configuración, lo que hace que sea realmente conveniente para el desarrollo local.

Acceso a bases de datos con Entity Framework primero código

Usaremos la compatibilidad con Entity Framework (EF) que se incluye en los proyectos de ASP.NET MVC 3 para consultar y actualizar la base de datos. EF es una API de datos de asignación relacional de objetos (ORM) flexible que permite a los desarrolladores consultar y actualizar los datos almacenados en una base de datos de forma orientada a objetos.

Entity Framework versión 4 admite un paradigma de desarrollo denominado primero código. Code-First permite crear un objeto de modelo escribiendo clases simples (también conocidas como POCO a partir de objetos CLR "antiguos sin formato") y puede incluso crear la base de datos sobre la marcha desde las clases.

Cambios en las clases de modelo

En este tutorial se aprovechará la característica de creación de bases de datos en Entity Framework. Sin embargo, antes de hacerlo, vamos a realizar algunos cambios menores en las clases del modelo para agregar algunas cosas que usaremos más adelante.

Adición de las clases del modelo de intérprete

Nuestros álbumes se asociarán con artistas, por lo que agregaremos una clase de modelo simple para describir un artista. Agregue una nueva clase a la carpeta models denominada Artist.cs con el código que se muestra a continuación.

namespace MvcMusicStore.Models
{
    public class Artist
    {
        public int ArtistId { get; set; }
        public string Name { get; set; }
    }
}

Actualización de las clases del modelo

Actualice la clase album como se muestra a continuación.

namespace MvcMusicStore.Models
{
    public class Album
    {
        public int      AlbumId     { get; set; }
        public int      GenreId     { get; set; }
        public int      ArtistId    { get; set; }
        public string   Title       { get; set; }
        public decimal  Price       { get; set; }
        public string   AlbumArtUrl { get; set; }
        public Genre    Genre       { get; set; }
        public Artist   Artist      { get; set; }
    }
}

A continuación, realice las siguientes actualizaciones en la clase Genre.

using System.Collections.Generic;
 
namespace MvcMusicStore.Models
{
    public partial class Genre
    {
        public int      GenreId     { get; set; }
        public string   Name        { get; set; }
        public string   Description { get; set; }
        public List<Album> Albums   { get; set; }
    }
}

Adición de la carpeta de datos de_de la aplicación

Agregaremos una aplicación_directorio de datos a nuestro proyecto para que contenga los archivos de base de datos de SQL Server Express. Los datos de_de la aplicación son un directorio especial en ASP.NET que ya tiene los permisos de acceso de seguridad correctos para el acceso a la base de datos. En el menú proyecto, seleccione Agregar carpeta ASP.NET y, a continuación,_datos de la aplicación.

Crear una cadena de conexión en el archivo Web. config

Agregaremos algunas líneas al archivo de configuración del sitio web para que Entity Framework sepa cómo conectarse a nuestra base de datos. Haga doble clic en el archivo Web. config que se encuentra en la raíz del proyecto.

Desplácese hasta la parte inferior de este archivo y agregue una sección <connectionStrings> directamente encima de la última línea, como se muestra a continuación.

<connectionStrings>
    <add name="MusicStoreEntities"
     connectionString="Data Source=|DataDirectory|MvcMusicStore.sdf"
     providerName="System.Data.SqlServerCe.4.0"/>
  </connectionStrings>  
</configuration>

Agregar una clase de contexto

Haga clic con el botón secundario en la carpeta modelos y agregue una nueva clase denominada MusicStoreEntities.cs.

Esta clase representará el Entity Framework contexto de base de datos y controlará nuestras operaciones de creación, lectura, actualización y eliminación. A continuación se muestra el código de esta clase.

using System.Data.Entity;
 
namespace MvcMusicStore.Models
{
    public class MusicStoreEntities : DbContext
    {
        public DbSet<Album> Albums { get; set; }
        public DbSet<Genre> Genres { get; set; }
    }
}

Es decir, no hay ninguna otra configuración, interfaces especiales, etc. Mediante la extensión de la clase base DbContext, nuestra clase MusicStoreEntities es capaz de controlar nuestras operaciones de base de datos. Ahora que hemos enlazado, vamos a agregar algunas propiedades más a las clases del modelo para aprovechar parte de la información adicional de nuestra base de datos.

Agregar los datos del catálogo de tiendas

Se aprovechará una característica de Entity Framework que agrega datos de "inicialización" a una base de datos recién creada. Esto rellenará previamente el catálogo de tiendas con una lista de géneros, artistas y álbumes. La descarga de MvcMusicStore-Assets. zip, que incluía los archivos de diseño del sitio usados anteriormente en este tutorial, tiene un archivo de clase con estos datos de inicialización, ubicado en una carpeta denominada Code.

Dentro de la carpeta Code/Models, busque el archivo SampleData.cs y colóquelo en la carpeta models en nuestro proyecto, como se muestra a continuación.

Ahora debemos agregar una línea de código para indicar Entity Framework sobre esa clase SampleData. Haga doble clic en el archivo global. asax en la raíz del proyecto para abrirlo y agregue la siguiente línea al principio del método de inicio de la aplicación_.

protected void Application_Start()
{
    System.Data.Entity.Database.SetInitializer(
    new MvcMusicStore.Models.SampleData());
    AreaRegistration.RegisterAllAreas();
    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);
 }

En este momento, hemos completado el trabajo necesario para configurar Entity Framework para nuestro proyecto.

Consultar la base de datos

Ahora vamos a actualizar nuestro StoreController de modo que, en lugar de usar "datos ficticios", llame a nuestra base de datos para consultar toda su información. Comenzaremos declarando un campo en el StoreController para que contenga una instancia de la clase MusicStoreEntities, denominada storeDB:

public class StoreController : Controller
{
    MusicStoreEntities storeDB = new MusicStoreEntities();

Actualizar el índice de almacén para consultar la base de datos

El Entity Framework mantiene la clase MusicStoreEntities y expone una propiedad de colección para cada tabla de nuestra base de datos. Vamos a actualizar la acción de índice de StoreController para recuperar todos los géneros de nuestra base de datos. Anteriormente lo hicimos mediante la codificación de datos de cadena. Ahora podemos usar la Entity Framework colección generes context:

public ActionResult Index()
{
    var genres = storeDB.Genres.ToList();
    return View(genres);
 }

No es necesario realizar ningún cambio en nuestra plantilla de vista, ya que seguimos devolviendo el mismo StoreIndexViewModel que hemos devuelto antes de que solo se devuelvan datos activos de nuestra base de datos.

Al ejecutar el proyecto de nuevo y visitar la dirección URL "/Store", ahora veremos una lista de todos los géneros de nuestra base de datos:

Actualización de la exploración y los detalles del almacén para usar datos activos

Con el método de acción/Store/Browse? Genre = [some-Genre] , buscamos un género por nombre. Solo se espera un resultado, ya que nunca tenemos dos entradas para el mismo nombre de género y, por tanto, podemos usar. Extensión Single () en LINQ para consultar el objeto de género adecuado como este (no lo escriba todavía):

var example = storeDB.Genres.Single(g => g.Name == "Disco");

El método único toma una expresión lambda como parámetro, que especifica que se desea un objeto de género único, de modo que su nombre coincida con el valor que hemos definido. En el caso anterior, vamos a cargar un objeto de género único con un valor de nombre que coincide con disco.

Sacaremos provecho de una característica Entity Framework que nos permite indicar otras entidades relacionadas que queremos cargar también cuando se recupera el objeto Genre. Esta característica se denomina modelado de resultados de consultas y nos permite reducir el número de veces que necesitamos tener acceso a la base de datos para recuperar toda la información que necesitamos. Queremos realizar una captura previa de los álbumes para el género que recuperemos, por lo que actualizaremos la consulta para incluirla en los géneros. incluya ("álbumes") para indicar que también queremos álbumes relacionados. Esto es más eficaz, ya que recuperará los datos del género y del álbum en una única solicitud de base de datos.

Con las explicaciones fuera del camino, este es el aspecto de nuestra acción de controlador de exploración actualizada:

public ActionResult Browse(string genre)
{
    // Retrieve Genre and its Associated Albums from database
    var genreModel = storeDB.Genres.Include("Albums")
        .Single(g => g.Name == genre);

    return View(genreModel);
}

Ahora podemos actualizar la vista de exploración del almacén para mostrar los álbumes que están disponibles en cada género. Abra la plantilla de vista (que se encuentra en/Views/Store/Browse.cshtml) y agregue una lista con viñetas de álbumes como se muestra a continuación.

@model MvcMusicStore.Models.Genre
@{
    ViewBag.Title = "Browse";
}
<h2>Browsing Genre: @Model.Name</h2>
<ul>
    @foreach (var album in Model.Albums)
    {
        <li>
            @album.Title
        </li>
    }
</ul>

La ejecución de la aplicación y la navegación a/Store/Browse? Genre = jazz muestra que los resultados se están extrayendo de la base de datos y muestran todos los álbumes del género seleccionado.

Realizaremos el mismo cambio en la dirección URL de/Store/Details/[id] y reemplazaremos los datos ficticios por una consulta de base de datos que cargue un álbum cuyo identificador coincida con el valor del parámetro.

public ActionResult Details(int id)
{
    var album = storeDB.Albums.Find(id);
 
    return View(album);
}

La ejecución de la aplicación y el desplazamiento a/Store/Details/1 muestra que ahora se extraen los resultados de la base de datos.

Ahora que la página de detalles de la tienda está configurada para mostrar un álbum por el identificador del álbum, vamos a actualizar la vista examinar para vincularla a la vista detalles. Usaremos HTML. ActionLink, exactamente como hicimos para vincular el índice de almacén al de la tienda al final de la sección anterior. A continuación se muestra el código fuente completo de la vista examinar.

@model MvcMusicStore.Models.Genre
@{
    ViewBag.Title = "Browse";
}
<h2>Browsing Genre: @Model.Name</h2>
<ul>
    @foreach (var album in Model.Albums)
    {
        <li>
            @Html.ActionLink(album.Title,
"Details", new { id = album.AlbumId })
        </li>
    }
</ul>

Ahora podemos examinar desde nuestra página de la tienda hasta una página de género, en la que se enumeran los álbumes disponibles y haciendo clic en un álbum en el que se pueden ver los detalles de ese álbum.