2013-01-11 8 views
6

Ich habe in ein bisschen ein Problem mit EF laufen für dieses Problem für die beste Praxis suchen:Arbeitseinheit, Entity Framework DbContext Scope

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); 

} 

Im TestEntityFramework_UOWImplementation() -Methode, seine feinen, i Rufen Sie einen Bereich für meine Arbeitseinheit an .. und erstellen Sie darin ein Repository.

Aber wenn ich willMaterials() wie unten .. Ich habe keinen Zugriff auf die Arbeitseinheit oder das Repository, es sei denn, ich übergebe es tatsächlich als Parameter! Das ist eindeutig nicht besonders nett.

Wie umgehen die Leute dieses Problem?

Vielen Dank im Voraus!

Neil

+1

Sollte nicht 'GetMaterial' eine Instanzmethode in der sein 'MaterialRepository' Klasse? –

+0

das ist ein guter Punkt! :) aber sag, es gäbe einen Fall, in dem du ein Where() machen würdest ... ich nehme an, diese wären auch im Repo. Vielen Dank! Jetzt, wo ich es aufgeschrieben sehe, ist es offensichtlich :) –

+0

Tatsächlich, sagen, es gab mehrere Repo-Abfragen erforderlich. Glauben Sie nicht, dass es jemals einen Fall geben würde, in dem die Abfrage außerhalb des Repos erfolgt? Oder sagen, ich hatte eine Methode namens CalculateMaterialPrices(), die eine Liste von Materialien benötigt, um zu berechnen.Würden Sie die repo GetMaterials() -Methode in der TestEntityFramework_UOWImplementation() - Methode oder in der CalculateMaterialPrices() -Methode aufrufen, wenn Letzteres, wie würden Sie auf den Repo zugreifen? oder bin ich hier nicht auf dem richtigen Weg! –

Antwort

0

Wenn jemand nach einem Weg um dies suchte, habe ich etwas ein bisschen anders gemacht.

Ich habe ein Dependency Injection-Framework (StructureMap) verwendet, um alle DIs zu verarbeiten. Jedes Mal, wenn ich ein Repository instanziiere, ruft es den DBContext vom Service Locator von StructureMap ab. Ich mache auch den dbcontext-Bereich für die Dauer der Anfrage vom Webserver.

Der Vorteil hier ist, dass jedes Mal, wenn ich einen DBContext abrufe oder einspreche, er den gleichen Kontext für die Dauer der Anfrage abrufen wird, was bedeutet, dass ich ihn über mehrere Methoden und Klassen verwenden kann! Ich gebe den Interface-Typ als generischen Parameter an den Konstruktor, was bedeutet, dass ich den Repo als verschiedene Kontexte zeigen kann. Hilfreich bei Anwendungen mit vielen dbcontexts.

Repo Constructor ZB:

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

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

Verbrauch:

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

und die Struktur Karte Abhängigkeit wie folgt aussieht:

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

ich interessiere mich für Meinungen !! –

3

in Ihrer Implementierung haben Sie nicht den Zugang zur Arbeitseinheit so. Was ich mache, ist ein IoC-Container und Dependency Injection, um damit umzugehen. Ich habe einen WCF-Dienst, der Unit of Work mit einem Repository-Muster gegen EF5 verwendet.

Sie können mehr über Repository-Muster, Arbeitseinheit lesen, und EF here aber im Grunde, was ich im Konstruktor meiner Dienstklasse I die Arbeitseinheit wie so injizieren: Ich

private readonly IUnitOfWork uow; 

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

Dann kann uow.WhateverMethod in meinen Repos überall im Dienst verwenden. Ich benutze Ninject, um die Injektion von IUnitOfWork zu behandeln. Hoffe es hilft dir.