2012-06-15 20 views
13

In che modo è possibile comunicare a Entity Framework lo Aggregates?Supporto root aggregato in Entity Framework

  1. durante il salvataggio di un aggregato, salva entità all'interno dell'aggregato
  2. durante l'eliminazione di un aggregato, eliminare le entità all'interno dell'aggregato
  3. alzare verificato un errore quando due utenti diversi tentano di modificare due entità diverse all'interno della stessa aggreate
  4. quando si carica un aggregato, offrono una vista consistente point-in-time dell'aggregato anche se c'è un certo ritardo di tempo prima di accedere tutte le entità all'interno dell'aggregato

(Entity Framework 4.3.1 Codice First)

+1

Quello che vuoi è Event Sourcing http://cqrs.wordpress.com/documents/events-as-storage-mechanism/. EF è praticamente inutile qui, solo un costoso overhead – MikeSW

+0

Grazie. Purtroppo non siamo in un ambiente che accetterebbe l'approvvigionamento degli eventi. –

+1

Dopo due anni di utilizzo di EF in una app Domain Driven Design: EF è chiamato "Entity Framework" e non "Aggregate Root Framework" per un motivo. –

risposta

6

EF offre funzionalità che ti permette definire degli aggregati e li utilizzano:

  1. Questa è la parte più dolorosa. EF funziona con i grafici delle entità. Se si dispone di un'entità come Fattura e questa entità ha una raccolta di entità InvoiceLine correlate, è possibile accedervi come aggregate. Se ci si trova in uno scenario collegato, tutto funziona come previsto ma in uno scenario distaccato (l'aggregato non viene caricato da EF o caricato da un'istanza di contesto diversa) è necessario associare l'aggregato all'istanza del contesto e dirgli esattamente cosa è stato modificato = impostare lo stato per ogni entità e associazione indipendente nel grafo degli oggetti.
  2. Questo viene gestito da cascata delete - se sono state caricate entità correlate, EF le cancellerà ma se non lo si deve è necessario eliminare la cascata configurata sulla relazione nel database.
  3. Questo viene gestito dai token di concorrenza nel database, in genere colonne di timestamp o rowversion.
  4. È necessario utilizzare il caricamento bisognoso e caricare tutti i dati insieme all'inizio (= punto di vista coerente) o si utilizzerà il caricamento lento e in tal caso non si avrà un punto di vista coerente perché il caricamento lazy caricherà lo stato corrente di relazioni ma non aggiornerà altre parti di aggregato che hai già caricato (e lo considero un killer delle prestazioni se provi ad implementare tale aggiornamento con EF).
+0

# 3 - EF rileverà un conflitto quando due utenti modificano diversi InvoiceLines sulla stessa fattura? # 4 - caricamento stimolante utilizzando .Include() su ogni query è doloroso e soggetto a errori –

+0

# 3 in tal caso sarà necessario assicurarsi che la modifica di "InvoiceLine" imposterà "Fattura" su stato modificato e l'aggiornamento della fattura sarà eseguita. –

+0

# 4 Il caricamento ansioso è forse doloroso nel tempo di codifica, ma è esplicito e mostra ciò che realmente accade. Puoi sempre rifattorizzare il tuo codice per utilizzare la base di query comune in cui verrà definito il caricamento ansioso. Il raggiungimento di un punto di vista coerente con il caricamento lento richiede il riordinamento coerente di tutti i dati caricati dall'aggregato. Il caricamento lento può essere negativo, ma sarà estremamente negativo. –

6

Ho scritto GraphDiff appositamente per questo scopo. Consente di definire un "limite aggregato" all'aggiornamento fornendo una mappatura fluente. L'ho usato nei casi in cui avevo bisogno di passare i grafici delle entità distaccati avanti e indietro.

Ad esempio:

// Update method of repository 
public void Update(Order order) 
{ 
    context.UpdateGraph(order, map => map 
     .OwnedCollection(p => p.OrderItems); 
} 

Quanto sopra direbbe Entity Framework per aggiornare l'entità dell'ordine e anche unire la raccolta di OrderItems. La mappatura in questo modo ci consente di garantire che Entity Framework gestisca solo il grafico entro i limiti che definiamo sull'aggregato e ignora tutte le altre proprietà. Supporta il controllo ottimistico della concorrenza di tutte le entità. Gestisce scenari molto più complicati e può anche gestire i riferimenti di aggiornamento in molti e molti scenari (tramite AssociatedCollections).

Spero che questo possa essere utile.