2011-01-12 29 views
7

Tengo 2 proyectos: una biblioteca de clases que contiene un modelo de marco de entidad EDM y un proyecto ASP.NET MVC independiente.Cómo actualizar EF 4 Entity en ASP.NET MVC 3?

Tengo problemas con la forma en que supone editar y guardar los cambios en una entidad que usa MVC. En mi controlador que tengo:

public class UserController : Controller 
    { 
     public ActionResult Edit(int id) 
     { 
      var rep = new UserRepository(); 

      var user = rep.GetById(id); 

      return View(user); 
     } 

     [HttpPost] 
     public ActionResult Edit(User user) 
     { 
      var rep = new UserRepository(); 

      rep.Update(user); 

      return View(user); 
     } 
    } 

Mi UserRepository tiene un método de actualización de la siguiente manera:

public void Update(User user) 
{ 
    using (var context = new PDS_FMPEntities()) 
    { 
     context.Users.Attach(testUser); 
     context.ObjectStateManager.ChangeObjectState(testUser, EntityState.Modified); 
     context.SaveChanges(); 
    } 
} 

Ahora, cuando hago clic en 'Guardar' en la página de edición de usuario, el parámetro user sólo contiene dos valores poblado: Id y FirstName. Supongo que se debe al hecho de que solo estoy mostrando esas dos propiedades en la vista.

Mi pregunta es esta, si estoy actualizando el nombre del usuario, y luego quiero guardarlo, ¿qué se supone que debo hacer con las otras propiedades User que no se muestran en la vista, ya que ahora contienen 0 o Valores NULL en el objeto user?

He estado leyendo mucho sobre el uso de entidades de código auxiliar, pero no llego a ninguna parte rápidamente, ya que ninguno de los ejemplos que he visto realmente funciona. es decir, sigo obteniendo excepciones relacionadas con EntityKey.

¿Alguien me puede indicar un buen tutorial/ejemplo de cómo actualizar las entidades EF 4 utilizando una clase de repositorio, llamada por un MVC front-end?

Respuesta

1

Bien, después de algún intento de prueba y error, parece que he encontrado una solución. Aquí está mi actualización Update método en el UserRepository:

public void Update(User user) 
{ 
    using (this.Context) 
    { 
     var tempUser = new User { usr_id = user.usr_id }; 

     this.Context.Users.Attach(tempUser); 
     this.Context.ApplyCurrentValues("Users", user); 
     this.Context.SaveChanges(); 
    } 
} 

Algunos de los otros ejemplos que probamos estaban muy cerca de la anterior, pero sólo puede perder la marca.

+2

@ Jason Evans - que se conoce como la técnica de talón, y sólo funciona para las propiedades escalares. Si tiene una propiedad de navegación como 'User.Addresses' a la que se está vinculando en su Vista, lo anterior no actualizará las direcciones. Le aconsejaría que recupere nuevamente el Usuario de la Base de Datos, luego use 'TryUpdateModel' para actualizar el objeto. Consulte mi pregunta/respuesta reciente aquí para obtener más información: http://stackoverflow.com/questions/4653834/asp-net-mvc-ef4-poco-repository-how-to-update-relationships/4666466#4666466 – RPM1984

+0

@ RPM1984 - Eso ahorraría molestias con las propiedades de navegación. La única preocupación que tengo con TryUpdateModel() es el diseño. Estoy tratando de asegurarme de que pueda usar un repositorio para tratar de obtener/guardar/eliminar cosas. Al usar TryUpdateModel(), ¿tiene sugerencias de un buen diseño sobre cómo codificar esto? Simplemente no quiero que el controlador se ocupe de ningún código relacionado con la base de datos si ves lo que quiero decir. –

+0

No, no estoy seguro de lo que quiere decir. Sin embargo, supongo que creará un método estándar de "Guardar" en su Repositorio, que "descubrirá" si se trata de un objeto nuevo/existente (basado en ID, por ejemplo). Por lo tanto, no necesita llamar a repository.Update o repository.Add. Simplemente TryUpdateModel y luego Guardar. Si usted no quiere que su controlador toque su entidad, no entiendo su preocupación. Los controladores están destinados a actualizar el modelo. Y todo lo que hace es actualizar un "objeto": su repositorio sigue preocupado por la persistencia de dicho objeto. – RPM1984

2

Recuperaría el usuario de la base de datos y actualizaría esa entidad. EF no puede simplemente saber mágicamente qué valores se deben modificar y cuáles no.

Si le preocupan los problemas de simultaneidad, debería almacenar la marca de tiempo en la vista, generalmente como un valor de formulario oculto.

0

me encontré con este tutorial en el sitio web asp.net a ser muy útil: Getting Started with EF using MVC - Updating Related Data

El método para prestar atención es TryUpdateModel que actualizará el modelo relacionado en la forma "estándar" (ajuste de la entidad a una estado modificado y pasando todo) y luego le permitirá personalizar cómo se actualizan ciertas propiedades.

Tuve un problema con las claves de entidad y esto me ayudó a superarlas.

+1

Gracias por su aporte. Lo mantendré en mi lista de recursos con respecto a EF. Muy apreciado. –

0

Esto es probablemente un poco tarde para ayudar a responder la pregunta, pero tal vez ayude a alguien más.Me parece que el problema principal que está teniendo es causado por el hecho de que la instancia de contexto de la base de datos que lee una entidad se elimina después de que se representa una página. Entonces, cuando intenta guardarlo, esta es una instancia nueva de un contexto, que por lo tanto no tiene conocimiento de la llamada de contexto anterior. Por lo tanto, Entity Framework tiene que actualizar todas las filas en la base de datos, porque no tiene forma de saber qué filas se cambiaron.

Dicho esto, el mejor método que he encontrado para guardar todos los datos antiguos y actualizar lo que deseo cambiar es realizar primero una nueva llamada a la base de datos, estableciendo toda la información necesaria para un Modele (o lo que sea que esté usando para almacenar sus datos) a lo que está actualmente en la base de datos. Luego realice los cambios necesarios en esa información y luego guarde el resultado en la base de datos.

Usted puede mirar en el tutorial sobre Ejecución básico CRUD aquí para obtener más información: http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-basic-crud-functionality-with-the-entity-framework-in-asp-net-mvc-application