Download ASP.NET MVC - Models
Document related concepts
no text concepts found
Transcript
Gerardo Grinman 5D ASP.NET MVC 3 ofrece una serie de herramientas y funciones para construir una aplicación utilizando sólo la definición de los objetos del modelo. Una vez que tenemos pensado el problema que queremos solucionar (ejemplo, la construcción de un carro de compras) podemos utilizar herramientas para construir controllers y views standards para escenarios tales como index, creación, edición y eliminación de objetos. Y este proceso de construcción se llama Scaffolding. Vayamos a crear un Carrito de Compras desde el comienzo con ASP.NET MVC. Primero tenemos que crear un nuevo proyecto. File -> New Project -> ASP.NET MVC 3 -> Internet Application y lo vamos a llamar CarritoCompras. Que objetos necesitamos modelar en nuestro proyecto? Lo primero que tenemos que poder hacer es la posibilidad de listar, crear, editar, ver y eliminar los distintos objetos de nuestro modelo. Para lograr eso tenemos que crear por cada objeto una clase que represente al mismo. public class Producto { public int ProductoId { get; set; } public int CategoriaId { get; set; } public string Nombre { get; set; } public decimal Precio { get; set; } public Categoria Categoria { get; set; } } public class Categoria { public int CategoriaId { get; set; } public string Nombre { get; set; } public string Descripcion { get; set; } } El proposito de la creacion de estas clases es la posibilidad de simular los atributos de los productos y de las categorias, tales como los nombres, precios, descripciones, etc. Asi como tenemos esos atributos, podemos agregar cuantos queramos y del tipo de datos que nos parezca. Ejemplo: la clase Producto tiene una propiedad de tipo Categoria que hace referencia a la categoria que el producto en cuestion pertenezca. Y vamos a llamar a la propiedad CategoriaId como una propiedad de Clave Foranea ya que hace referencia directa a una categoria en particular. Nuestro paso siguiente va a ser la creación de los administradores (controladores) de cada uno de nuestros objetos del modelo para poder editar su información. Scaffolding en ASP.NET MVC puede generar el código base que necesitamos para crear, leer, editar y eliminar (CRUD). Scaffolding puede examinar los tipos de datos de nuestro modelo y luego generar el controller y sus views asociadas. Scaffolding sabe como llamar a los controllers y las views, y que código necesita cada componente para ahorrarnos trabajo. Como casi todo en ASP.NET MVC si no nos gusta el comportamiento base que nos ofrece Scaffolding, se puede sobrescribir, modificar o incluso no utilizar y construir nuestro código a mano. Es decir, no es requerido para poder construir una aplicación pero la ventaja es que nos puede ahorrar mucho tiempo al momento de desarrollarla. Finalmente, NO hay que esperar que Scaffolding construya la aplicación entera, ya que lo único que va a realizar es ahorrarnos tiempo en las tareas típicas de desarrollo. Empty Controller Crea una clase controller que lo unico que deja es un Index action con nada de código y sin generar una View. Controller with Empty Read/Write Actions Esta plantilla agrega un controller para el proyecto con Index, Details, Create, Edit y Delete actions. Las acciones en el interior no son del todo vacías, pero no llevará a cabo ningún trabajo útil hasta que añadamos nuestro código y creemos sus views. Controller with Read/Write Actions and Views, Using Entity Framework Esta plantilla no sólo genera el controller con todo, sino que también genera todas las Views necesarias y el código para persistir y recuperar información de una base de datos. EF es un framework de mapeo Objeto-Relacional que sabe como guardar objetos de .NET en una base de datos relacional y devolver esos objetos a través de una consulta LINQ. EF soporta el tipo de desarrollo llamado Code First. Code First significa que podemos comenzar guardando y devolviendo informacion de una base de datos SQL Server sin haber creado primero una base de datos. Por lo que primero escribimos clases en C# planas y el EF va a saber donde y como guardar las instancias de esas clases. EF, tal como ASP.NET MVC sigue un par de convenciones para hacernos la vida mas facil. Por ejemplo, si queremos guardar un objeto de tipo Producto en la base de datos, EF asume que todos los datos van a ser guardados en una tabla llamada Productos. Si tenemos una propiedad llamada ID o NombreDeClaseId va a asumir que es la clave primaria de la tabla y le asigna un atributo de tipo Auto Incremental a la columna. También existen convenciones para la creación de claves foráneas, nombres de bases de datos y mas. Cuando utilizamos el enfoque Code First, la puerta a la base de datos va a ser una clase de tipo DbContext. Esta clase derivada de DbContext va a tener propiedades de tipo DbSet<T>, donde cada <T> va a representar el tipo de objeto que vamos a persistir. public class ModelMvcApplicationDB : DbContext { public DbSet<Producto> Productoes { get; set; } public DbSet<Categoria> Categorias { get; set; } public DbSet<Usuario> Usuarios { get; set; } } Utilizando las clases de DbContext podemos obtener por ejemplo los productos utilizando una query LINQ de la siguiente forma: var db = new ModelMvcApplicationDB(); var productos = from producto in db.Productos select producto; El metodo Include que podemos ver en el metodo Index de ejemplo le dice al EF que permite cargar en una simple query todos los datos relacionados de sus objetos, en este caso, carga la categoria asociada al producto. Otro metodo de carga puede ser el Lazy Loading Strategy, que hace una query a demanda por cada item. Es decir, si tenemos 100 productos, va a realizar por cada producto una query extra para obtener sus categorias. Como podemos ver una vez generada la plantilla con Scaffolding, se van a generar los controllers y sus vistas asociadas con una funcionalidad basica. Si no existe y no se configura ninguna base de datos en la configuracion del sitio (en el web.config), el EF va a crear la BD utilizando las convenciones mencionadas previamente. Si la BD no existe, el EF va a crear una en la instancia local del SQL Sever Express con el mismo nombre que la clase heredada de DbContext. Como se ve en el DER (Diagrama de Entidad Relación), el EF crea automaticamente las tablas para guardar los productos y las categorias. Tambien utiliza las propiedades y los tipos de datos para crear los distintos campos de la BD y deduce cuales serian sus claves primarias. La tabla EdmMetadata se encarga de asegurar que el esquema de la BD este sincronizado con el modelo de datos de la aplicación. En caso de que alteremos nuestro modelo de datos el EF dependiendo de cómo configuremos la aplicación va a re crear la BD nuevamente o va a tirar un mensaje de error. Para evitar que la aplicación nos tire error al cambiar nuestro modelo de datos y mantener asi nuestra BD sincronizada con la aplicación podemos decirle al EF que vuelva a crear la BD cada vez que la aplicación comienza o cuando unicamente detecta que se realizo un cambio en el modelo de datos. protected void Application_Start() { Database.SetInitializer(new DropCreateDatabaseAlways<ModelMvcApplication.Models.ModelMvcA pplicationDB>()); AreaRegistration.RegisterAllAreas(); RegisterGlobalFilters(GlobalFilters.Filters); RegisterRoutes(RouteTable.Routes); } Pero… Que pasa con los datos ya cargados? Tenemos que volver a cargar todo nuevamente? No podemos tener datos pre cargados? En el caso de que queramos comenzar nuestra aplicación para pruebas siempre con datos, podemos crear una clase nueva y heredarla de DropCreateDatabaseAlways y sobreescribir el metodo Seed. Finalmente nuestro metodo Application_Start del Global.asax quedaria algo asi: protected void Application_Start() { Database.SetInitializer(new ModelDbInitializer()); AreaRegistration.RegisterAllAreas(); RegisterGlobalFilters(GlobalFilters.Filters); RegisterRoutes(RouteTable.Routes); } Finalmente, nuestro trabajo se reduce a: 1. Implementar nuestro modelo de clases. 2. Scaffold nuestros controllers y views. 3. Elegir nuestra estrategia de inicializacion de base de datos.