21

Mam projekt na MVC. Wybraliśmy EF dla naszych transakcji DB. Stworzyliśmy kilku menadżerów dla warstwy BLL. Znalazłem wiele przykładów, w których używany jest „using” oświadczenie, tjWykorzystanie EF (entity framework) instrukcji "using"

public Item GetItem(long itemId) 
    { 
     using (var db = new MyEntities()) 
     { 
      return db.Items.Where(it => it.ItemId == itemId && !it.IsDeleted).FirstOrDefault(); 
     } 
    } 

Tutaj tworzymy nową instancję DBcontext MyEntities(). Używamy "using", aby uzyskać "ensure the correct use of IDisposable objects."

To tylko jedna metoda w moim managerze. Ale mam ich więcej niż dziesięć. Za każdym razem, gdy wywołuję dowolną metodę z menedżera, używam "using", a następnie statemant i tworzę kolejny DBcontext w pamięci. Kiedy garbage collector (GC) wyrzuci je? Kto wie?

Istnieje jednak inna możliwość zastosowania metod menedżera. Tworzymy zmienną globalną:

private readonly MyEntities db = new MyEntities(); 

i używać DBcontext w każdej metodzie bez „using” oświadczeniu. I metoda wygląda następująco:

public Item GetItem(long itemId) 
{ 
    return db.Items.Where(it => it.ItemId == itemId && !it.IsDeleted).FirstOrDefault(); 
} 

Pytania:

  1. Jaki jest właściwy sposób używając zmiennej DBcontext?
  2. Co by było, gdybyśmy nie używali oświadczenia "usage" (ponieważ wpływa to na wydajność) - GC zrobi wszystko za to?

Jestem "nowicjuszem" w używaniu EF i nadal nie znalazłem jednoznacznej odpowiedzi na to pytanie.

+0

Zależy od tego, jak daleko chcesz to zrobić. Najlepiej byłoby, gdybyś nie stworzył go w swoim kontrolerze, ale zamiast tego ** Inject ** it (IoC/DI) w ten sposób, niezależnie od tego, który kontroler wywołujący (Factory) może określić czas życia Kontekstu. – Belogix

+0

Dlaczego wpływa to na wydajność? Zmierzyłeś go i doszedłeś do wniosku, że tracisz wydajność? A GC go nie wyrzuca, sam je wyrzucasz, ponieważ używasz instrukcji użycia. – Maarten

Odpowiedz

11

Myślę, że znajdziesz wiele sugerujących ten styl wzoru. Nie tylko ja lub Henk DBContext handling

  • Tak, najlepiej przy użyciu oświadczenia o DBContext podtypów
  • Nawet lepiej jednostkę wzorów prac, które są zarządzane z wykorzystaniem, o które mają kontekst i unieszkodliwiają kontekście Just 1 of many UoW examples, this one from Tom Dykstra
  • The Jednostka Work Manager powinien być nowy dla każdego żądania Http.
  • Kontekst NIE jest bezpieczny dla wątków, więc upewnij się, że każdy wątek ma własny kontekst.
  • Pozwól EF zapisywać cache za kulisami.
  • Czasy tworzenia czasu testu. po kilku żądaniach HTTP. Czy nadal masz problem?
  • Spodziewaj się problemów, jeśli kontekst zostanie zapisany w pamięci statycznej. jakikolwiek równoczesny dostęp będzie bolesny i jeśli korzystasz z równoległych wywołań AJAX, przyjmij 90 +% szans na problemy, jeśli używasz statycznego pojedynczego kontekstu.

For some performance tips, well worth a read

+1

Przy okazji "Tylko jeden z wielu przykładów UoW, ten od Julie Lerman" autorstwa Toma Dykstry, a nie Julie Lerman –

+0

Thx za poprawkę Paul –

1

Prawidłowe lub najlepszym sposobem praktyka stosowania zmiennej DBContext jest z użytkowania.

using (var db = new MyEntities()) 
    { 
     return db.Items.Where(it => it.ItemId == itemId && !it.IsDeleted).FirstOrDefault(); 
    } 

Korzyścią jest to, że wiele rzeczy dzieje się automatycznie dla nas.Na przykład po zakończeniu bloku kodu wywoływane jest wywołanie.

za MSDN EF Working with DbContext

Trwałość związku rozpoczyna się, gdy jest tworzona instancja i kończy się, gdy przykład jest albo usuwane lub porządkowania pamięci. Użyj opcji , jeśli chcesz, aby wszystkie zasoby, które elementy sterujące kontekstem mają być umieszczone na końcu bloku, były . Kiedy używasz, kompilator automatycznie tworzy blok try/finally i wywołuje dispose w końcu bloku. .