2011-01-12 9 views
7

Ho due progetti: una libreria di classi contenente un modello di Entity Framework EDM e un progetto MVC ASP.NET separato.Come aggiornare l'entità EF 4 in ASP.NET MVC 3?

sto avendo problemi con come il vostro supponiamo di modificare e salvare le modifiche a un'entità utilizzando MVC. Nel mio controller ho:

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

mio UserRepository ha un metodo di aggiornamento in questo modo:

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

Ora, quando faccio clic su 'Salva' nella pagina Modifica utente, il parametro user contiene solo due valori populated: Id e FirstName. Prendo questo è dovuto al fatto che sto solo visualizzando queste due proprietà nella vista.

La mia domanda è questa, se sto aggiornando il nome dell'utente e poi voglio salvarlo, cosa dovrei fare riguardo alle altre proprietà User che non sono state mostrate nella vista, dal momento che ora contengono 0 o Valori NULL nell'oggetto user?

Ho letto un sacco su come utilizzare le entità stub, ma mi sto da nessuna parte veloce, in quanto nessuno degli esempi che ho visto effettivamente funzionare. Ad esempio, continuo a ricevere eccezioni relative a EntityKey.

Qualcuno mi può puntare a un buon tutorial/esempio di come aggiornare EF 4 entità utilizzando una classe repository, chiamato da un front-end MVC?

risposta

1

OK, dopo alcune prove ed errori, cerco di aver trovato una soluzione. Ecco il mio aggiornata Update metodo nella 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(); 
    } 
} 

Alcuni degli altri esempi che ho provato erano molto vicini a quanto sopra, ma proprio colto nel segno.

+2

@ Jason Evans - che si riferisce a come la tecnica di stub, e funziona solo per le proprietà scalari. Se si possiede una proprietà di navigazione come "User.Addresses" a cui si sta vincolando nella Vista, quanto sopra non aggiornerà gli indirizzi. Ti consiglierei di recuperare nuovamente l'Utente dal DB, quindi usando 'TryUpdateModel' per aggiornare l'oggetto. Vedere la mia domanda/risposta recente qui per maggiori informazioni: http://stackoverflow.com/questions/4653834/asp-net-mvc-ef4-poco-repository-how-to-update-relationships/4666466#4666466 – RPM1984

+0

@ RPM1984 - Ciò farebbe risparmiare fastidio con le proprietà di navigazione. L'unica preoccupazione che ho con TryUpdateModel() è la progettazione. Sto cercando di assicurarmi di poter utilizzare un repository per gestire l'acquisizione/salvataggio/eliminazione di materiale. Usando TryUpdateModel(), hai suggerimenti di buon design su come codificarlo? Non voglio che il controller gestisca qualsiasi codice relativo al database se vedi cosa intendo. –

+0

No, non sono sicuro di cosa intendi. Prenderò comunque un'ipotesi, creare un metodo standard "Salva" nel tuo repository, che "calcola" se si tratta di un oggetto nuovo/esistente (basato su ID, ad esempio). Quindi non è necessario chiamare repository.Update o repository.Add. Basta provareUpdateModel quindi Salva. Se il tuo riferimento a te non vuole che il tuo controller tocchi la tua entità, non capisco la tua preoccupazione. I controllori hanno lo scopo di aggiornare il modello. E tutto ciò che sta facendo è aggiornare un "oggetto" - il tuo repository è ancora interessato alla persistenza di detto oggetto. – RPM1984

2

Vorrei recuperare l'utente dal database e aggiornare quell'entità. EF non può solo sapere magicamente quali valori dovrebbero essere modificati e quali no.

Se siete preoccupati per problemi di concorrenza si avrebbe bisogno di memorizzare il timestamp nella vista - di solito come un valore forma nascosta.

0

Ho trovato questo tutorial sul sito web asp.net per essere molto utile: Getting Started with EF using MVC - Updating Related Data

Il metodo di prestare attenzione a è TryUpdateModel che aggiornerà il modello relativo alla maniera "standard" (impostazione dell'entità di un stato modificato e passando tutto in) e poi ti permetterà di personalizzare il modo in cui certe proprietà vengono aggiornate.

Mi sono imbattuto in problemi con le chiavi di entità e questo mi ha aiutato a superare quelli.

+1

Grazie per l'input. Terrò questo nella mia lista di risorse riguardo EF. Molto apprezzato. –

0

Questo è probabilmente un po 'tardi per aiutare a rispondere alla domanda, ma forse vi aiuterà qualcun altro.Mi sembra che il problema principale che si sta avendo è causato dal fatto che l'istanza di contesto del database che legge un'entità viene eliminata dopo il rendering di una pagina. Quindi, quando provi a salvarlo, questa è una nuova istanza di un contesto, che quindi non ha conoscenza della precedente chiamata di contesto. Entity Framework deve quindi aggiornare tutte le righe nel database, perché non ha modo di sapere quali sono le righe modificate.

Detto questo, il metodo migliore che ho trovato per il salvataggio di tutti i vecchi dati e l'aggiornamento di ciò che voglio cambiare è di effettuare prima una nuova chiamata al database, impostando tutte le informazioni richieste per un Modello (o qualsiasi cosa tu stia utilizzando per memorizzare i tuoi dati) su ciò che è attualmente nel DB. Quindi apportare le modifiche necessarie a tali informazioni e quindi salvare il risultato nel DB.

Potete guardare il tutorial su Implementazione di base CRUD qui per maggiori informazioni: 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