2011-12-05 11 views
7

Actualización de un objeto con MVC3MVC3 con EF 4.1 y EntityState.Modified

tengo un modelo que pueda modificar, por favor vea el ejemplo siguiente:

[HttpPost] 
public ActionResult Edit(Company c) 
{ 
     if (ModelState.IsValid) 
     { 
      db.Entry(c).State = EntityState.Modified; 
      db.SaveChanges(); 
      return RedirectToAction("Index"); 
     } 
     return View(c); 
} 

El modelo tiene otros campos que no son que se muestra en la vista y no puede ser modificado por el usuario, pero cuando hago clic en el botón de enviar, los campos que no se muestran en la vista se establecen en nulo.

¿Puedo de alguna manera dejar que EF sepa que no debe modificar ciertos campos? Gracias.

Respuesta

12

En general, es mejor no vincular directamente al objeto de entidad, en lugar de eso, cree un modelo de edición y vincule a eso.

Después de todo ... ¿qué impide que alguien publique valores que no quiere cambiar con este enfoque?

El principal problema aquí es el hecho de que los cambios vinculantes modelo MVC las propiedades en el modelo antes de su contexto, por tanto, en un marco de la entidad no sabe qué valores han cambiado (y, por tanto, que debe ser actualizado)

Has mitigado eso ligeramente con db.Entry(c).State = EntityState.Modified;, pero eso le dice a la estructura de la entidad que todo el registro se ha actualizado.

lo haría normalmente lo siguiente:

  1. se unen a un modelo específicamente para este primer controlador
  2. crear una instancia de la clase de entidad que desea actualizar, poner la identificación en consecuencia y adjuntarlo a la
  3. contexto
  4. actualización de las propiedades en la entidad a ser el mismo que el modelo que aglutinaba a (objeto está conectado y, por lo tanto marco de la entidad es el seguimiento de las columnas que se están cambiando ahora)
  5. SaveChanges

Paso 3 es un poco tedioso, por tanto, considerar el uso de una herramienta como automapper para facilitar las cosas

Editar:

[HttpPost] 
    public ActionResult Edit(Company c) 
    { 
     if (ModelState.IsValid) 
     { 
      Company dbCompayObjct = new Company { companyId = c.companyId }; 
      db.Company.Attach(dbCompayObjct); 

      dbCompanyObjct.CompanyName = c.CompanyName; 
      dbCompanyObjct.City = c.City; 

      db.SaveChanges(); 

      return RedirectToAction("Index"); 
     } 
     return View(c); 
    } 
+0

Hola Martin, gracias por su respuesta, modifico la acción de edición al siguiente código, ¿podría decirme si esto es lo que quería decir? srry acaba de comenzar el aprendizaje y la EF MVC [HttpPost] pública ActionResult Editar (Compañía c) { si (ModelState.IsValid) { Compañía dbCompanyObjct = db.Company.Find (c.companyID); dbCompanyObjct.CompanyName = c.CompanyName; dbCompanyObjct.City = c.City; db.SaveChanges(); return RedirectToAction ("Índice"); } return Ver (c); } Además, ¿podría explicarme qué es Automapper? ¿como lo uso? gracias – Ben

+0

me disculpo por el código no alineado, difícil de leer, no tengo idea de por qué no se está alineando ... por favor, si el código es correcto. – Ben

+0

Eso funcionará, publicaré una actualización rápida para mostrar que no necesita el primer Find –

3

Aparentemente está sobreescribiendo su registro existente con un registro incompleto. Cuando utiliza el método anterior, reemplazará por completo el existente.

O bien debe completar todos los campos que no desea reemplazar con los valores existentes, o necesita obtener el registro existente y modificar los campos que desea modificar, luego guárdelo.

+0

No hay manera de especificar de algún modo en la clase de modelo, por ejemplo, el campo "fecha de aplicación" para no permitir modificar el valor, de manera similar, no podemos modificar la clave primaria del entidad modelo? – Ben

+2

@ user1042528 - no estás entendiendo. Está reemplazando el registro completo, no actualizando campos individuales. No importa si puede evitar que se escriban campos, ya que en realidad no está escribiendo sobre ellos. Estás reemplazando el registro completo.Es como la diferencia entre reemplazar una botella de cerveza en un paquete de seis, y simplemente obtener un paquete de 6 diferente que tiene solo una botella. No estás reemplazando a los otros 5 con nada, estás reemplazando el registro completo. –

+0

Gracias por su explicación, ¿así es como actualiza los campos individuales? [HttpPost] público ActionResult Edit (Company c) { si (ModelState.IsValid) { Company dbCompanyObjct = db.Company.Find (c.companyID); dbCompanyObjct.CompanyName = c.CompanyName; dbCompanyObjct.City = c.City; db.SaveChanges(); return RedirectToAction ("Índice"); } return Ver (c); } – Ben

0

reflexión no siempre es malo, a veces es su amigo:

public ActionResult Edit(Company c) 
{ 
    if (ModelState.IsValid) 
    { 
     Company UpdateC = db.Company.find(c.CompanyID);   
     foreach (var property in typeof(Company).GetProperties()) 
     { 
      var propval = property.GetValue(c); 
      if (propval != null) 
      { 
       property.SetValue(UpdateC, propval); 
      } 
     } 

     db.SaveChanges(); 
     return RedirectToAction("Index"); 
    } 
    return View(c); 
} 
Cuestiones relacionadas