2012-10-25 13 views
5

Ho appena visto i video di Julie Lermans sull'utilizzo di contesti limitati in EF (http://www.pluralsight.com/training/Courses/TableOfContents/efarchitecture) e ora sto provando a elaborare il modo migliore per implementarlo (utilizzando POCO). Le due opzioni che vedo sono di avere un modello edmx che definisce tutto e quindi di creare DbContexts per includere le entità appropriate o di avere modelli edmx separati per ogni contesto e utilizzare DbContexts creato automaticamente.Contesti limitati (Db) nell'architettura Entity Framework

Qualcuno ha qualche idea di ciò che è meglio o dei pro/contro di entrambi?

IMHO: Per un singolo modello è molto meno classi e molto più riutilizzo del codice (anche se queste classi vengono create automaticamente così davvero sarà solo la funzionalità aggiuntiva che verrà duplicata manualmente), ma io avrà un sacco di classi in un posto e per le classi che devono essere specializzate queste dovranno avere nomi diversi. Per esempio. Cliente, CustomerForFunctionalityX, CustomerForFunctionalityB.

Con i modelli separati posso essere molto più severo su ciò che entra in un contesto come rimuovere una proprietà non ha bisogno di essere un'entità completamente nuova, e posso nominare tutto come vorrei (cioè tutti i modelli possono usare un Oggetto del cliente anche se differisce tra i modelli), ma ora ogni contesto ha entità completamente diverse anche se stanno tutti mappando solo sulla stessa tabella - il che può anche rendere più difficile il loro passaggio tra i contesti (questo però non dovrebbe essere necessario troppo spesso altrimenti significa che i contesti sono stati definiti errati).

+0

Perché non utilizzare l'unità di modello di lavoro per creare unità di lavoro che espongono solo le entità con cui un determinato team lavorerà? Se tutti i team lavorano contro lo stesso database, in realtà dovrebbe esserci solo un team centrale che gestisce il database. I contesti limitati sembrano indirizzare al codice un problema che è meglio indirizzato con la struttura del team, IMO. – Maess

+0

Sicuramente l'aggiunta del pattern UOW potrebbe aiutare e mi piace il pattern UOW, sebbene possa aggiungere complessità.Il motivo principale per cui mi piacciono gli edmx separati è che un edmx di grandi dimensioni può diventare non gestibile e anche la creazione di edmx limitati fa sì che gli sviluppatori del database possano vedere esattamente quali entità appartengono a un contesto, piuttosto che dover creare entità personalizzate per tutti gli UOW in uno modello: sarebbe bello avere questa separazione nell'intero modello, incluso il modello di database. – user1671016

risposta

0

Ti suggerisco di leggere su quali contesti sono limitati e quali problemi cercano di risolvere. Dal contesto limitato definition:

Definire esplicitamente il contesto all'interno del quale si applica un modello. Definire esplicitamente i limiti in termini di organizzazione del team, utilizzo all'interno di parti specifiche dell'applicazione e manifestazioni fisiche come basi di codice e schemi di database. Mantenere il modello rigorosamente coerente all'interno di questi limiti, ma non essere distratto o confuso da problemi esterni.

Avere un singolo modello EDMX violerebbe tale limite esplicito. Probabilmente puoi immaginare l'attrito che potrebbe verificarsi quando team di contesti diversi lavorano sullo stesso modello EDMX. Nel tuo caso, tuttavia, potresti pensare che il costo di quel confine esplicito e dell'integrazione tra i contesti sia troppo alto. L'utilizzo di Shared Kernel consente di condividere il modello EDMX tra i contesti.

+0

Julie nei suoi video sembra usare un edmx ma che non si è seduto con me. Sono d'accordo che un singolo edmx potrebbe causare attriti (e anche un enorme modello!), Tuttavia, poiché esiste un solo database, non penso che in questo scenario possiamo essere completamente coerenti con tutte le regole. Dovrei ancora provare a seguire questo schema anche se non posso avere successo con tutte le sue parti? – user1671016

0

ma ora ogni contesto ha entità completamente diversi anche se sono tutti solo la mappatura allo stesso tavolo

questo è un segno che non si può effettivamente bisogno molteplici contesti (BC) delimitata. L'obiettivo principale di una BC è functional cohesion e se il tuo modello finisce per avere una grande quantità di chat tra BC (in altre parole l'accoppiamento), allora è probabilmente un'indicazione che un singolo BC sarebbe più appropriato. Prima di isolare BC diversi, considera se il tuo modello sarebbe meglio servito dal partizionamento in moduli (namespace in .NET). Dai un'occhiata a Implementing Domain-Driven Design per ulteriori informazioni.

Inoltre, spesso i tempi, una varietà di requisiti di query possono far sembrare che siano in gioco più BC, dove in realtà hai solo bisogno di modi diversi di vedere la stessa entità. Questo è molto diverso dall'avere entità completamente diverse tutte insieme. Potresti utilizzare lo read-model pattern per risolvere questo problema.

+0

L'isolamento delle aree di funzionalità è quello che utilizzo principalmente contesti limitati, tuttavia ritengo improbabile che si possa fare ciò senza sovrapposizioni di entità. Non vorrei certamente permettere molti accoppiamenti tra i contesti in quanto ciò significherebbe che ho diviso le aree in modo errato piuttosto che un problema con il modello. – user1671016

+0

Nel mio scenario il sistema sarà composto da diversi prodotti che condividono tutti un singolo database. Ci saranno alcune funzionalità condivise e alcune specifiche del prodotto, quindi sto cercando di trovare il modo migliore per dividerlo. L'idea di contesti definiti chiaramente definiti sembra un buon modo per separare la funzionalità e quindi utilizzare gli spazi dei nomi per fornire l'ambito del prodotto (specifico del prodotto o comune) di tale funzionalità. Suona come una buona idea? Molte entità saranno in sola lettura e quindi l'utilizzo del contesto limitato consente di farlo in modo pulito. – user1671016

+0

Se si esegue il partizionamento del dominio in più BC, è necessario anche suddividere il database attorno a tali BC, altrimenti i limiti potrebbero perdere. Chiediti se hai un'entità condivisa o se hai diverse prospettive dell'entità. Le BC possono certamente condividere l'entità _identità_, nel qual caso una BC può "collegare" funzionalità a un'entità da un'altra BC. Puoi fornire maggiori dettagli sul tuo dominio? – eulerfx

1

Anche io sto provando contesti limitati e ho incontrato un (piccolo?) Problema con gli schemi. Inizialmente ho creato due contesti, uno per i dati del dominio e uno per i dati del tipo di controllo (sia le informazioni di revisione delle modifiche all'entità che le informazioni sul processo). Inizialmente, ho scoperto che il database creava solo tabelle da un contesto e ignorava l'altro. Ho supposto che deriva i due contesti da un contesto di base,

public class BaseContext<TContext> : DbContext where TContext : DbContext 

genera il database completo, ma non sembrava di farlo.

Un modo per aggirare questo era creare un contesto "principale" che fa riferimento a tutte le entità, ma non esporlo al modello. Questo ha funzionato bene, ma ora c'è un piccolo problema con gli schemi db.

Poiché il nostro personale di supporto utilizza SSMS per eseguire il debug del sistema, ho pensato che sarebbe una buona idea cambiare lo schema lungo le stesse linee del contesto limitato, quindi ho specificato lo schema nel contesto principale (OnModelCreating() sovrascrive metodo con il contesto principale):

modelBuilder.Entity<Address>() 
      .HasKey(b => new {b.AddressId,b.EffectiveStartDate}) 
      .ToTable("Addresses", "Esr"); 

dove "Esr" è lo schema. Tuttavia, nel tentativo di scrivere dati con il contesto limitato, si verifica un errore che indica che il contesto limitato utilizza lo schema "dbo". Sono sicuro che c'è un modo per aggirare questo. Ho la sensazione fastidiosa che questo non valga la pena di tutti gli sforzi.

Certi contorni limitati conferiscono all'applicazione un'applicazione più pulita e mi piace l'idea di strutturare il codice per adattarlo alla struttura del dominio, in quanto ciò avvicina l'architettura generale alle specifiche e aiuta a pensare ai test.

D'altra parte, i miei colleghi programmatori avranno difficoltà a scegliere le entità giuste quando codificano contro un singolo contesto monolitico?

La separazione dei contesti è molto più utile se applicata nell'area di supporto o UAT e queste persone devono lavorare con l'applicazione in termini di processo aziendale generale.

+0

È interessante notare che questo problema scompare quando si passa dalla configurazione fluente alle annotazioni dei dati. Bisogna cambiare TUTTA la configurazione, poiché una volta che EF vede annotazioni di dati sembra ignorare la fluente (che ho lasciato sul posto). Immagino che funzioni perché tutti i contesti funzionano dalle stesse classi POCO, quindi è possibile definire uno schema db comune nell'annotazione dei dati. – Ackroydd

+0

Dopo un po 'di sperimentazione, ho provato a fare lo split logico a livello di repository ("Repository Bounded"?). Poiché il repository si trova tra dbcontext e il modello, sembra la struttura giusta. L'unico problema è che alcune parti del modello funzionano genericamente con entrambi i repository, quindi per determinare quale dovrebbe essere usato ho dovuto usare i parametri di tipo liberamente. Il risultato funziona ma non è il codice più bello. – Ackroydd

1

Stiamo discutendo di questo problema esatto ora e anch'io ho guardato i video di Julies e il DDD ricercato. Vorrei che il mio accesso ai dati riflettesse l'unità di lavoro, ma stiamo incontrando un problema in cui un nome di tabella non può essere utilizzato in più di un EDMX.

Diciamo che ho tabelle Customer, CustomerOrder, Order, OrderInventory, Item. Su uno schermo voglio solo visualizzare le informazioni del cliente, quindi il mio EDMX per questo ha solo il cliente. Ora un altro caso d'uso è rappresentato da tutte le fatture per un cliente, in questo caso d'uso ho Cliente, Ordine Cliente, Ordine, OrderInventory e Item. Otteniamo questa eccezione: L'associazione del tipo CLR al tipo EDM è ambigua perché più tipi CLR corrispondono al tipo EDM "Cliente". Tipo CLR in precedenza trovato 'A.Customer', tipo CLR appena trovato 'B.Customer'.

Come stai girando questo messaggio di errore? Stai rinominando ogni tabella che viene duplicata su tutti i file EDMX?

Problemi correlati