2009-12-22 1 views
5

Stiamo scrivendo un'applicazione WPF utilizzando il framework Entity (Silverlight con i servizi RIA per la precisione). Usiamo un ObjectContext condiviso attraverso l'applicazione in modo che possiamo beneficiare della condivisione dei dati tra i moduli.Entity Framework ObjectContext nell'applicazione windows/WPF/Silverlight

Il problema è che se l'utente durante il suo lavoro si apre diciamo vendite storiche, viene caricato nell'ObjectContext e rimane lì fino alla fine dell'applicazione. Quindi dovrebbe essere usato un altro modello.

So che ObjectContexts deve essere utilizzato come singola unità di lavoro. Ma poi, come fai a sapere che altre parti dell'applicazione sanno che qualcosa è cambiato e che dovrebbero ricaricare i loro dati?

Modifica: Ok, EventAggregator, ma in questo modo tutte le altre parti ricaricheranno i dati (probabilmente molti di essi duplicati). Probabilmente anche molti eventi sarebbero necessari per tutti i tipi di gruppi di entit.

Come risolvete questi problemi? La mia soluzione attuale è una sorta di compromesso: utilizzare un ObjectContext condiviso per i dati principali utilizzati dall'intera applicazione in modo che possano essere condivisi e aggiornati automaticamente. E per la grande quantità di dati, usa un nuovo ObjectContext separato. Qualche idea migliore?

Esiste un modo per "rilasciare" entità dal proprio DataContext in modo che Garbage Collector possa svolgere il proprio lavoro e rilasciare la memoria?

risposta

2

Aspetta, è WPF o Silverlight? In questo caso, sono molto diversi e la mia risposta sarebbe diversa.

WPF Soluzione

In WPF vorrei creare un unico ObjectContext per modulo. In questo modo, il contesto durerà fino a quando la forma stessa. Dovresti quindi implementare un sistema di eventi in modo che quando salvi le modifiche a un'entità, puoi avvisare gli altri moduli di cui potrebbero aver bisogno per aggiornare i loro dati (ad esempio, INotifyPropertyChanged). Oren Eini wrote a pretty good article on this architecture using NHibernate in MSDN magazine. Dovresti essere in grado di ottenere il concetto di architettura dal suo articolo.

Silverlight Soluzione

Ora, Silverlight è diverso. In sostanza Silverlight ti consente solo di avere un modulo nella tua applicazione. Sì, ci sono alcuni trucchi che puoi fare per navigare nella visualizzazione radice del modulo in "pagine" diverse, ma è pur sempre un modulo e l'utente non può aprire più finestre in una RIA Silverlight. Per questo motivo, creerò uno .Net Object Rage Services RIA per istanza RIA Silverlight. Ricorda, i Servizi RIA non sono una vera e propria connessione al tuo database, ma solo un oggetto di memorizzazione nella cache e di modifica delle modifiche collegato a un servizio web. Quindi, è perfettamente accettabile lasciare questo oggetto in esistenza per periodi di tempo più lunghi perché non sta legando alcuna risorsa del server. Se Silverlight RIA apre più finestre del browser o ha più di un oggetto Silverlight, è necessario disporre di un ObjectContext per istanza Silverlight.

Sul server, si utilizza un ObjectContext di Entity Framework nel servizio Web e dovrebbe durare solo per la durata di una richiesta. Più gli apolidi possono rendere i tuoi servizi, più scalabili e performanti saranno. Volete aprire il vostro ObjectContext EF, usarlo e chiuderlo il prima possibile.


EDIT:

Se tutti si vogliono fare è staccare un oggetto dal contesto oggetto, allora si può solo utilizzare il metodo context.Detach(entity). È possibile trovare un example of how to do this on MSDN.

+0

Con questa applicazione, stiamo parlando di Silverlight. Usando Prism/Caliburn, credo che non sia un problema avere un singolo ObjectContext per view (modulo?). Anche in questo caso, il problema è: se ci sono molti dati da caricare sul client? Per ora come ora, la soluzione migliore sarebbe quella di creare un ObjectContext condiviso per le entità di base che vengono utilizzate attraverso l'intera applicazione in modo che siano sincronizzate automaticamente e separare ObjectContexts per il caricamento di una grande quantità di dati, ad es. alcuni rapporti storici. – gius

+0

Non proverei a inviare blocchi di dati veramente grandi al client. Invece, vorrei filtrare sul server e restituire solo i risultati che il cliente vuole vedere in quel momento. Gli umani non possono leggere 100.000 record, quindi non inviarli a un umano. Invece, lascia che il problema sia una ricerca/filtro e invii solo i risultati al cliente. Se si stanno creando report, creare i dati di riepilogo aggregati sul server. Ad esempio, sarebbe meglio calcolare il volume delle vendite mensili sul server e inviare un singolo numero al client piuttosto che vedere 5000 record di vendite. –

+0

Questo è vero, ma se l'utente vede in qualsiasi momento durante la vita dell'applicazione diciamo le pagine 1, 10, 20, quei dati saranno ancora in memoria. D'altra parte, l'utilizzo di un ObjectContext separato e il paging dei dati potrebbero risolvere il problema dei dati di grandi dimensioni in memoria. – gius

1

È possibile utilizzare il modello di repository. Un ulteriore livello di astrazione tra UI e DAL.

Rendi statiche e osservabili le raccolte di dati nel repository. Quindi, ogni volta che il repository ne aggiorna uno, il livello dell'interfaccia utente dovrebbe aggiornarsi. È un'idea.

+0

Questo non risolve il mio problema - le collezioni sarebbe rimasto sul client, quindi se c'è per esempio 1 GB di dati nel database, prima o poi, verrà caricato anche sul client. D'altra parte, questo potrebbe mostrare una possibile soluzione. Grazie per l'idea! – gius

0

Utilizzare ObservableCollections in ObjectContext. Utilizzare un evento che si attiva su NotifyPropertyChange. Utilizzare un modello di pubblicazione/sottoscrizione tra i modelli di visualizzazione per informarli della modifica e utilizzarli per aggiornare le altre visualizzazioni.

+1

Tutte le raccolte create dall'EF sono ObservableCollection e le entità utilizzano NotifyPropertyChanged. Il problema è che non posso utilizzare solo ObjectContext durante l'intero ciclo di vita dell'applicazione perché non verranno rilasciati dati dalla memoria una volta caricati nell'appliaction. D'altra parte, l'utilizzo di ObjectContext separato per ogni singola azione causerà problemi nell'aggiornamento dei dati: gli stessi dati verranno caricati più volte da più punti e la sincronizzazione significherebbe eventi personalizzati per ogni tipo di dati. La domanda principale è se c'è qualche struttura/modello per questo problema. – gius