2013-01-11 16 views
6

ho incontrato un po 'di un problema con EF cercando la migliore prassi per questo problema:unità di lavoro, Entity Framework DbContext Ambito

public void TestEntityFramework_UOWImplementation() 
{ 
    using (UnitOfWorkInventory uow = new UnitOfWorkInventory()) 
    { 
     IMaterialRepository repos = new MaterialRepository(uow); 

     Material mat = GetMaterial("Mikes Material", 1); 

     mat.CostPrice = 20; 

     repos.InsertOrUpdate(mat); 

     uow.Commit(); 
    } 
} 

private Material GetMaterial(string sku, int clientId) 
{ 
    IMaterialRepository repos = new MaterialRepository(new UnitOfWorkInventory(); 

    return repos.Find(sku, clientId); 

} 

Nel metodo TestEntityFramework_UOWImplementation(), la sua fine, i call crea un ambito per la mia unità di lavoro .. e crea un repository al suo interno.

Ma quando voglio ottenereMaterials() come di seguito .. Non ho accesso all'unità di lavoro o al repository, a meno che non lo passi effettivamente come parametro! Questo chiaramente non è particolarmente bello.

Come si aggira questo problema ??

Grazie in anticipo!

Neil

+1

caso non 'GetMaterial' essere un metodo di istanza nella 'Classe MaterialRepository'? –

+0

questo è un buon punto! :) ma diciamo che c'era un caso in cui si vorrebbe fare un Where() ... suppongo che anche questi sarebbero nel repository. Grazie! ora che lo vedo scritto in modo ovvio :) –

+0

In realtà, diciamo che c'erano diverse richieste di richieste di risarcimento. non credi che ci sarebbe mai un caso in cui l'interrogazione sarebbe fatta al di fuori del repo? O dire che avevo un metodo chiamato CalculateMaterialPrices() che necessitava di un elenco di materiali da calcolare.Chiameresti il ​​metodo Reper GetMaterials() nel metodo TestEntityFramework_UOWImplementation() o nel metodo CalculateMaterialPrices(), se quest'ultimo, come faresti ad accedere al repository? o non sono sulla strada giusta qui! –

risposta

0

Se qualcuno cercava un modo per aggirare questo, ho fatto qualcosa di un po 'diverso.

Ho usato un framework Injection Dependency (StructureMap) per gestire tutti i DI, quindi ogni istante istanzio un repository recupererà DBContext dal Service Locator di StructureMap. Faccio anche l'ambito dbcontext per la durata della richiesta dal server web.

Il vantaggio è che ogni volta che recupero o inietti un DBContext, recupererà lo stesso contesto per la durata della richiesta, il che significa che posso usarlo su più metodi e classi! Passo il tipo di interfaccia come parametro generico al costruttore, il che significa che posso puntare il repository come contesti diversi. Utile in applicazioni dove ci sono molti dbcontexts.

Repo Costruttore Esempio:

public class PurchaseOrderRepository<TDbContext> : GenericRepository<PurchaseOrder>, IPurchaseOrderRepository<TDbContext> where TDbContext : DbContext 
{ 

     public PurchaseOrderRepository() 
      : base((TDbContext)ObjectFactory.GetInstance<TDbContext>()) 
     { 
     } 
} 

Usage:

//resolves the request scope InventoryContext... 
var pRepos = new PurchaseOrderRepository<IInventoryContext>(); 

e la struttura della mappa delle dipendenze si presenta come:

For<IInventoryContext>().HttpContextScoped().Use<InventoryContext>(); 
+0

sono interessato alle opinioni !! –

3

Nell'implementazione non avrai accesso al l'unità di lavoro del genere. Quello che faccio è usare un contenitore IoC e l'iniezione di dipendenza per gestirlo. Ho un servizio WCF che utilizza l'unità di lavoro con un modello di repository contro EF5.

Si può leggere di più su Pattern Repository, unità di lavoro, e EF here ma in fondo quello che faccio è nel costruttore della mia classe di servizio inietto l'unità di lavoro in questo modo:

private readonly IUnitOfWork uow; 

    public LoanService(IUnitOfWork unitOfWork) 
    { 
     uow = unitOfWork; 
    } 

Poi ho può usare uow.WhateverMethod nei miei repository ovunque nel servizio. Io uso Ninject per gestire l'iniezione di IUnitOfWork. Spero che ti aiuti.

Problemi correlati