2009-09-09 12 views
17

Jestem całkowitym nowicjuszem w Entity Framework i ASP.Net MVC, uczyłem się głównie z samouczków, bez głębokiego zrozumienia któregokolwiek z nich. (Posiadam doświadczenie w .Net 2.0, ADO.Net i WebForms)Entity Framework - Jak powinienem instancji mój obiekt "Entities"

Moje obecne wątpliwości wynikają ze sposobu, w jaki umieszczam obiekty moich obiektów.

zasadzie robię to w moich kontrolerami:

public class PostsController : Controller { 

    private NorthWindEntities db = new NorthWindEntities(); 

    public ActionResult Index() { 
      // Use the db object here, never explicitly Close/Dispose it 
    } 
} 

robię to w ten sposób, bo okazało się, że w pewnym blogu MSDN, który wydawał wystarczająco miarodajne mi się, że zakłada się, że był to właściwy sposób .
Jednak czuję się nieswojo w tej kwestii. Mimo że oszczędza mi dużo kodu, jestem przyzwyczajony do robienia:

using (NorthWindEntities db = new NorthWindEntities() { 
} 

W każdej metody, która potrzebuje połączenia, a jeśli ta metoda nazywa innym, że będzie to potrzebne, to będzie przechodzić jako db parametr do nich. W ten sposób zrobiłem wszystko z obiektami połączeniowymi, zanim istniało Linq-SQL.

Inną rzeczą, która mnie niepokoi, jest to, że narzędzie NorthWindEntities implementuje IDisposable, co zgodnie z konwencją oznacza, że ​​powinienem nazywać to metodą Dispose(), a ja nie.

Co o tym sądzisz?
Czy poprawnie jest wstawiać obiekt Obiekty, tak jak ja? Czy powinien dbać o swoje połączenia, otwierając i zamykając je dla każdego zapytania?
A może powinienem być disposing to jawnie z using() klauzula?

Dzięki!

Odpowiedz

21

Sam sterownik implementuje IDisposable. Możesz więc przesłonić Unieszkodliwić i pozbyć się wszystkiego (na przykład kontekstu obiektu), który zainicjujesz, gdy sterownik zostanie utworzony.

Kontroler działa tylko tak długo, jak pojedynczy wniosek. Zatem używanie wewnątrz akcji i posiadanie jednego kontekstu obiektu dla całego kontrolera jest dokładnie taką samą liczbą kontekstów: 1.

Duża różnica między tymi dwoma metodami polega na tym, że czynność zakończy się przed renderowaniem widoku. Więc jeśli utworzysz obiekt ObjectContext w instrukcji using wewnątrz akcji, obiekt ObjectContext zostanie usunięty przed renderowaniem widoku. Więc lepiej przeczytać cokolwiek z kontekstu, który potrzebujesz zanim akcja się zakończy. Jeśli model przekazany do widoku jest leniwą listą, taką jak IQueryable, usuniesz kontekst przed renderowaniem widoku, powodując wyjątek, gdy widok próbuje wyliczyć IQueryable. Z kolei, jeśli zainicjalizujesz ObjectContext po zainicjowaniu kontrolera (lub napisz leniwy kod inicjujący powodujący jego inicjalizację podczas działania) i usuniesz ObjectContext w Controller.Dispose, to kontekst będzie nadal być w pobliżu podczas renderowania widoku. W takim przypadku bezpieczne jest przekazywanie produktu IQueryable do widoku. Kontroler zostanie usunięty wkrótce po renderowaniu widoku.

W końcu, byłabym niedbała, gdybym nie wskazała, że ​​to prawdopodobnie zły pomysł, aby kontroler był w ogóle świadom istnienia struktury Entity. Przyjrzyj się użyciu osobnego zestawu dla modelu i wzorca repozytorium, aby kontroler rozmawiał z modelem. Wyszukiwarka Google pojawi się całkiem sporo na ten temat.

+0

OK, to ma sens. Teraz pytanie brzmi ... Czy robię coś niepoprawnie? Czy naprawdę muszę pozbyć się obiektu Obiekty? Co się stanie, jeśli nie? Czy będę "przeciekać" połączenia z serwerem SQL? –

+1

ObjectContext.Dispose nie robi wiele (patrz Reflektor). Ale rozsądnie jest założyć, że to się może zmienić, a ty * możesz * pozbyć się go. –

3

Robisz tu dobry punkt.Jak długo powinien istnieć obiekt ObjectContext? Wszystkie wzorce i książki praktyk (takie jak Dino Esposito's Microsoft-NET-Architecting-Applications) mówią, że DataContext nie może żyć długo, ani nie powinien być buforowany.

Zastanawiam się, dlaczego nie mam w twoim przypadku klasy ControllerBase (nie jestem świadomy implementacji MVC, więc nie przejmuj się) gdzie ObjectContext zostanie zainicjowany raz dla wszystkich kontrolerów. Szczególnie pomyśl o Identity Map Pattern, który jest już wdrożony przez Entity Framework. Mimo że musisz zadzwonić do innego kontrolera jako swojego kontrolera postów, nadal będzie działał z tym samym kontekstem i poprawi również wydajność.

Powiązane problemy