Después de mucho tiempo sin escribir por este medio, creo que por falta de tiempo y trabajo entre otros, pero estoy tratando de retomar esta costumbre para compartir mis nuevas experiencias, ya que por cuestiones de la vida estoy emprendiendo el aprendizaje de tecnologías nuevas para mi, aunque no para la comunidad. Por lo que si alguien se ha topado con las mismas eventualidades leyendo y no ha encontrado aún una solución quiero compartirla con cualquiera que lea este blog.
Pues bien ya después de esta larga introducción, entremos en materia. Por el momento me encuentro aprendiendo MVC como les decía y tengo de referencia el libro Apress Pro.ASP.NET MVC3 aunque a la vez voy tratando de acoplarlo a MVC4 y luego que domine esto iniciaré con MVC5, pues bien me encuentro actualmente en el capítulo 8/9. Utilizo por el momento VS2010.
Para introducir un poco, el ejemplo utiliza Ninject como DI, Entity Framework para trabajar el bindeo de la base de datos SQL Express que nos instala VS por defecto. Pues bien en el capítulo 8 se crea una aplicación MVC referente a una pequeña tienda de deportes, hasta ese capitulo todo funciona siguiendo los pasos del libro, pero en el capítulo 9 se nos plantea hacer la administración del catálogo de artículos y es cuando la modificación que recomienda el libro no nos es funcional.
El CRUD tendría la siguiente lógica
El libro nos recomienda el siguiente código para hacer la modificación:
Paso #1. Agregar a nuestra interfaz la firma del método SaveProduct, que será utilizado para modificar o crear un nuevo artículo mediante Entity Framework
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SportsStore.Domain.Entities;
namespace SportsStore.Domain.Abstract
{
public interface IProductRepository
{
IQueryable<Product> Products { get; }
void SaveProduct(Product product);
void DeleteProduct(Product product);
}
}
Paso #2. Implementamos el método de la interfaz
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ninject.Activation;
using SportsStore.Domain.Abstract;
using SportsStore.Domain.Entities;
using System.Data.Entity;
namespace SportsStore.Domain.Concrete
{
public class EfProductRepository : IProductRepository
{
private EfDbContext _context=new EfDbContext();
public IQueryable<Product> Products
{
get { return _context.Products; }
}
public void SaveProduct(Product product)
{
if (product.ProductID == 0)
{
_context.Products.Add(product);
}
_context.SaveChanges();
}
public void DeleteProduct(Product product)
{
_context.Products.Remove(product);
_context.SaveChanges();
}
}
}
En este paso se hace la actualización de objeto en la base de datos, asumiendo que si el ProductID es igual a cero, quiere decir que es un nuevo producto y por lo tanto debe hacer un nuevo registro y para ello se agrega al contexto, de lo contrario debería actualizar la entidad actual. Sin embargo es aquí cuando surge un problema y es que en ningún momento se le ha dicho al contexto que debe actualizarse, por lo que nunca se hará una actualización y justamente acá fue donde surgió mi interrogante en como resolver el problema, ya que según el libro debía funcionar. Pues bien buscando un poco en la internet encontré varios métodos, sin embargo plantearé el que creo que entendí más facilmente y que de alguna manera se parece a mi antigua forma de trabajar sin la utilización de Entity Framework:
Paso #3. Actualizar la acción del controlador "AdminController" que se desarrolla dentro del ejemplo de la siguiente manera:
[HttpPost]
public ActionResult Edit(Product product,HttpPostedFileBase image)
{
if (ModelState.IsValid)
{
//_repository.SaveProduct(product);
Product p = _repository.Products.FirstOrDefault(x => x.ProductID == product.ProductID);
if ((p != null) && (image!=null))
{
p.ProductID = product.ProductID;
p.Price = product.Price;
p.Category = product.Category;
p.Description = product.Description;
p.Name = product.Name;
p.ImageMimeType = image.ContentType;
p.ImageData=new byte[image.ContentLength];
image.InputStream.Read(p.ImageData, 0, image.ContentLength);
}
else
p = product;
_repository.SaveProduct(p);
TempData["message"] = string.Format("{0} has been saved", product.Name);
return RedirectToAction("Index");
}
else
{
// there is something wrong with the data values
return View(product);
}
}
Básicamente lo que se ha hecho es que similar a cuando la acción carga con el método GET, buscamos el producto que coincida con el ProductID que se ha seleccionado en la lista de productos y posteriormente validamos si la entidad esta vacía, sino lo está quiere decir entonces que encontró un objeto en el planteamiento del libro solo sería necesario hacer el "SaveProduct" pasando la entidad que viene como parámetro, pero al hacer esto si no se enviara un producto nuevo como lo plantea el libro no haría el update, por lo que debemos indicarle al contexto el objeto que deseamos actualizar y entonces a esa instancia le igualamos las propiedades del objeto que es enviado debido a que actualizaremos todos los campos y seguido de esto guardamos el producto y esto entonces le indica a Entity Framework que deseo actualizar dicho producto con los valores que le envié.
Listo con estas lineas podemos hacer que el ejemplo del libro permita actualizar sin ningún problema.

No hay comentarios:
Publicar un comentario