2011-12-05 17 views
7

aggiornamento di un oggetto con MVC3MVC3 con EF 4.1 e EntityState.Modified

Ho un modello che posso modificare, vedere l'esempio di seguito:

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

Il modello ha altri campi che non sono visualizzato nella vista e non può essere modificato dall'utente, ma quando faccio clic sul pulsante di invio i campi che non sono stati visualizzati nella vista sono stati impostati su null.

Posso in qualche modo informare EF di non modificare determinati campi? Grazie.

risposta

12

In genere è preferibile non associare direttamente l'oggetto entità, piuttosto creare un modello di modifica e associarlo a tale.

Dopo tutto ... cosa significa impedire a qualcuno di postare valori non modificati con questo approccio?

Il problema principale è il fatto che modello mvc modifiche vincolanti le proprietà nel modello prima della sua in un contesto quindi il quadro entità non sa che valori sono stati modificati (e quindi quale devono essere aggiornati)

L'hai mitigato leggermente con db.Entry(c).State = EntityState.Modified; ma questo indica al framework di entità che l'intero record è stato aggiornato.

io normalmente fare quanto segue:

  1. Bind ad un modello specifico per questo controller prima
  2. Creare un'istanza della classe di entità che si desidera aggiornare, impostare l'ID di conseguenza e allegarlo alla contesto
  3. Aggiornare le proprietà nei confronti del soggetto di essere lo stesso del modello che binded a (oggetto è collegato e quindi Entity framework è il monitoraggio quali colonne vengono modificate ora)
  4. SaveChanges

Fase 3 è un po 'noioso quindi considerare l'utilizzo di uno strumento come automapper per rendere le cose più facili

Edit:

[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

Ciao Martin, grazie per la tua risposta, modifico l'azione di modifica al seguente codice, potresti per favore fammi sapere se questo è ciò che intendevi. srry appena iniziato EF apprendimento e MVC [HttpPost] pubblico ActionResult Edit (società C) { se (ModelState.IsValid) { impresa dbCompanyObjct = db.Company.Find (c.companyID); dbCompanyObjct.CompanyName = c.CompanyName; dbCompanyObjct.City = c.City; db.SaveChanges(); return RedirectToAction ("Index"); } visualizzazione di ritorno (c); } Inoltre, potresti spiegarmi che cos'è l'automapper? Come lo uso? grazie – Ben

+0

Mi scuso per il codice non stato allineato, difficile da leggere, non ho idea del motivo per cui non è allineato ... consiglio se il codice è corretto. – Ben

+0

Che funzionerà, pubblicherò un rapido aggiornamento per mostrare che non è necessario il primo Trova –

3

Apparentemente si sta sovrascrivendo il record esistente con un record incompleto. Quando si utilizza il metodo sopra, esso sostituirà completamente quello esistente.

È necessario compilare tutti i campi che non si desidera sostituire con i valori esistenti oppure è necessario ottenere il record esistente e modificare i campi che si desidera modificare, quindi salvarlo.

+0

Non c'è modo di specificare in qualche modo nella classe del modello per esempio il campo "applicationDate" per non consentire di modificare il valore, in modo simile come non possiamo modificare la chiave primaria del entità modello? – Ben

+2

@ user1042528 - non stai capendo. Stai sostituendo l'intero record, non aggiornando i singoli campi. Non importa se puoi impedire che i campi vengano scritti, poiché in realtà non stai scrivendo su di essi. Stai sostituendo l'intero record.È come la differenza tra sostituire una bottiglia di birra in una confezione da sei e ottenere semplicemente una confezione da 6 diversa che contiene solo una bottiglia. Non stai sostituendo gli altri 5 con niente, stai sostituendo l'intero record. –

+0

Thx per la tua spiegazione, è così che aggiorni i singoli campi? [HttpPost] pubblico ActionResult Edit (società C) { se (ModelState.IsValid) { impresa dbCompanyObjct = db.Company.Find (c.companyID); dbCompanyObjct.CompanyName = c.CompanyName; dbCompanyObjct.City = c.City; db.SaveChanges(); return RedirectToAction ("Index"); } visualizzazione di ritorno (c); } – Ben

0

riflessione non è sempre il male, a volte è tuo amico:

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); 
} 
Problemi correlati