Se è già nel context, non serve fare l'attach, basta aggiornarla con UpdateModel.

Ciao!
m.
4 messaggi dal 11 marzo 2008
Ciao Marco, il tuo articolo è molto interessante e sto utilizzando le classi unitOfWork in tutte quelle pagine aspx in cui si presenti uno scenario multiutente al fine di gestire correttamente le problematiche di concorrenza.
Mi sorgono alcuni dubbi, che vorrei proporti:

1. Una pagina aspx caratterizzata da 3 UpdatePanel dove ognuno dei quali ha un button SALVA... dopo aver effettuato il salvataggio tramite l'istruzione
UnitOfWorkContainer.Instance.CommitTransaction(this.unitOfWorkId);
viene successivamente chiusa la transazione e rimosso il contesto (così come da te ben spiegato!).
Succede che se si vuole nuovamente salvare i dati premendo il button, l'istruzione genera un ERRORE perchè il contesto non è più disponibile (Invalid PersistenceContext id); per ovviare a questo, dopo l'istruzione di salvataggio ho inserito l'istruzione per una nuova transazione di business
this.unitOfWorkId = UnitOfWorkContainer.Instance.BeginTransaction<ObjectContext>();
E? CORRETTI QUELLO CHE HO FATTO ? O PROPONI UN ALTERNATIVA ?

2. Come ci si deve comportare in una pagina aspx che va a dialogare/modificare con 2 TABELLE diverse?
Vanno duplicate le rooutine ?

Ti ringrazio in anticipo e mi scuso? ma sono un neofita di Entity?
Buon Lavoro
Ciao!

Premetto che dovrei guardare da vicino il tuo codice per capire meglio, in ogni modo...

1) Direi che se un UpdatePanel salva il tuo oggetto, la transazione di business è conclusa. Quindi è corretto iniziarne un'altra come fai tu.

2) Nessun problema. Ti basta applicare le tue modifiche sugli oggetti, alla fine tramite CommitTransaction viene invocato il metodo ObjectContext.SaveChanges che si preoccupa di salvare i dati aggiornati.

A presto,
Marco
4 messaggi dal 11 marzo 2008
Ciao Marco...grazie per la risposta
per il 1 QUESITO...
ho una pagina aspx con un controllo TABCONTAINER con 3 PANEL TAB ed ognuno con un suo UPDATEPANEL.
Ho diviso le informazioni provenienti da una singola tabella nei 3 PANEL TAB.
Esempio: Tabella ORDINI
1 TAB PANEL (ID ORDINE) (IDCLIENTE) (IDVENDITORE) ECC...
2 TAB PANEL (STATO ORDINE) (DATA ORDINE) ECC...
3 TAB PANEL (DETTAGLIO ORDINE) (IMPORTI) ECC...
Ogni TAB PANEL contiene il button SALVA che consente di salvare sul database - tabella ORDINI solo le relative informazioni presenti e non tutte le informazioni di un ordine... questo per ridurre la quantità di dati che vengono salvati. Che ne pensi?

per il 2 QUESITO...non ho capito !
devo duplicare la routine
- private Customer loadCustomer(int customerId)
- private Customer customer

Grazie ancora... Ciao
2 messaggi dal 18 settembre 2009
Ciao,
anzitutto complimenti per l'articolo e gli spunti che hai fornito.
Avrei piacere di avere un tuo punto di vista riguardo un'applicazione
ASP.NET che vorrei realizzare e che deriva da un gestionale scritto in Visual Basic 6.
Sto riscrivendo gli oggetti di business e relative logiche applicative integrando
il tutto con EF 4.1 Code first come ORM verso un db SqlServer.
Inizialmente il porting riguarda un'area limitata del gestionale dal momento che
vorrei capire qual'è l'impatto dell'architettura sia da un punto di vista di gestione
del codice sia delle prestazioni: infatti il db consta di circa 250 tabelle tra loro relazionate.
Del progetto iniziale ho realizzato le classi di mapping che consentono la navigazione tra i business object e che vengono poi istanziate nel "OnModelCreating" del "DbContext".
Secondo la tua esperienza e le dimensioni del progetto finale (250 tabelle) "conviene" utilizzare la "Cache" per "parcheggiare" le istanze caricate e memorizzate nell' "ObjectContext" oppure conviene scegliere una strada alternativa? e quale potrebbe essere?
L'istanza di un "DbContext" per utente (per una media di 70 utenze contemporanee)
delle suddette dimensioni potrebbe impattare in modo pesante sui server?
L'architettura prevede il bilanciamento su più server come posso scalare il "DbContext"...su db?

Grazie
2 messaggi dal 18 settembre 2009
Ciao,
anzitutto complimenti per l'articolo e gli spunti che hai fornito.
Avrei piacere di avere un tuo punto di vista riguardo un'applicazione
ASP.NET che vorrei realizzare e che deriva da un gestionale scritto in Visual Basic 6.
Sto riscrivendo gli oggetti di business e relative logiche applicative integrando
il tutto con EF 4.1 Code first come ORM verso un db SqlServer.
Inizialmente il porting riguarda un'area limitata del gestionale dal momento che
vorrei capire qual'è l'impatto dell'architettura sia da un punto di vista di gestione
del codice sia delle prestazioni: infatti il db consta di circa 250 tabelle tra loro relazionate.
Del progetto iniziale ho realizzato le classi di mapping che consentono la navigazione tra i business object e che vengono poi istanziate nel "OnModelCreating" del "DbContext".
Secondo la tua esperienza e le dimensioni del progetto finale (250 tabelle) "conviene" utilizzare la "Cache" per "parcheggiare" le istanze caricate e memorizzate nell' "ObjectContext" oppure conviene scegliere una strada alternativa? e quale potrebbe essere?
L'istanza di un "DbContext" per utente (per una media di 70 utenze contemporanee)
delle suddette dimensioni potrebbe impattare in modo pesante sui server?
L'architettura prevede il bilanciamento su più server come posso scalare il "DbContext"...su db?

Grazie
14 messaggi dal 20 novembre 2006
Ciao Marco, complimenti per l'articolo.
Sto provando ad utilizzare le classi UnitofWork dell'esempio in un'apllicazione asp.net mvc 4 con entity framework 4.0 code first.
Ho organizzato l'applicazione nel modo seguente.
Ho un controllo base "BaseController" dal quale ereditano tutti i controller. In questo controller ho due proprietà "unitOfWorkId" e "unitOfWork" identiche a quelle dell'esempio eccetto per il fatto che unitOfWorkId è di tipo string invece di Guid.
Sempre all'interno di BaseController facio l'override di "Initialize" scrivendo quanto segue all'interno :
base.Initialize(rc);

if (unitOfWorkId == null)
{
// Primo caricamento della pagina: iniziamo una nuova
// transazione di business
this.unitOfWorkId = UnitOfWorkContainer.Instance.BeginTransaction<PannelloAgenti.Contesto.CustomerContest>();
}

// ad ogni esecuzione della pagina, recuperiamo la unitOfWork corrente
this.unitOfWork = UnitOfWorkContainer.Instance.GetUnitOfWork<PannelloAgenti.Contesto.CustomerContest>(this.unitOfWorkId);

if (unitOfWork == null)
{
// la unitOfWork è scaduta; qui si può prevedere un messaggio
// in cui si avvisa l'utente e lo si invita a ri-effettuare
// l'operazione dall'inizio
// In questo esempio ci limitiamo a sollevare un'eccezione
throw new InvalidOperationException("UnitOfWork scaduta!");
}

L'accesso a i dati avviene tramite una classe chiamata BusinessManager, la quale riceve nel construttore un oggetto di tipo UniOfWork.
Nelle action dei controller l'accesso aviene in questo modo :
ViewAttComm app = new ViewAttComm();

BusinessManager BM = new BusinessManager(UnitOfWorkContainer.Instance.GetUnitOfWork<CustomerContest>(base.unitOfWorkId));

app.AttComm = BM.CaricaAttCommerciale();

Il mio problema è che ricevo sempre questo errore "The operation cannot be completed because the DbContext has been disposed."

Hai qualche idea del perchè !? Riesci a darmi la giusta imbeccata, dove sbaglio !?

Ciao e grazie.

Mario Muti

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.