2011-10-12 18 views
49

Jeśli mam zadeklarowane relacja podmiot w moim modelu jako wirtualny to nie ma potrzeby korzystania z instrukcji Include w mojej kwerendy LINQ, prawda ?? -Entity Framework 4.1 Wirtualne Właściwości

Dla ex: To jest mój model klasy :

public class Brand 
{ 
    public int BrandID { get; set; } 
    public string BrandName { get; set; } 
    public string BrandDesc { get; set; } 
    public string BrandUrl { get; set; } 

    public virtual ICollection<Product> Products { get; set; } 
} 

Teraz, dla powyższej klasy modelu, nie muszę używać var brandsAndProduct = pe.Brands.Include("Products").Single(brand => brand.BrandID == 22);.

Zamiast tego, mogę po prostu użyć prostego var brandsAndProduct = pe.Brands.Where(brand => brand.BrandID == 22); i automatycznie udostępnię powiązaną jednostkę, gdy uzyskam do niej dostęp.

Czy mam rację w moim rozumieniu?

Proszę również powiedzieć mi, w jakich sytuacjach powinienem preferować jedno nad drugim?

Odpowiedz

158

Masz rację, ale zasada jest bardziej złożona, aby działała zgodnie z oczekiwaniami. Jeśli zdefiniujesz swoją właściwość nawigacji, to w czasie wykonywania EF utworzy nową klasę (dynamiczny serwer proxy) wywodzącą się z klasy Brand i użyje jej zamiast niej. Ta nowa dynamicznie tworzona klasa zawiera logikę do ładowania właściwości nawigacji po uzyskaniu dostępu po raz pierwszy. Ta funkcja nazywa się leniwym ładowaniem (lub lepszym, przezroczystym, leniwym ładowaniem).

Jakie zasady należy spełnić, aby uczynić tę pracę:

  • Wszystkie właściwości nawigacyjnych w klasie musi być virtual
  • stworzenie dynamicznego proxy nie musi być wyłączony (context.Configuration.ProxyCreationEnabled). Jest on domyślnie włączony.
  • Leniwe ładowanie nie może być wyłączone (context.Configuration.LazyLoadingEnabled). Jest on domyślnie włączony.
  • Podmiot musi być dołączony (domyślnie, jeśli wczytuje się obiekt z bazy danych) do kontekstu, a kontekst nie może być usuwany = leniwy ładowanie działa tylko w zakresie kontekstu życia używanego do załadowania go z bazy danych (lub w przypadku, gdy przyłączono serwer proxy)

Przeciwieństwem leniwego ładowania jest ładowanie wymagające i to właśnie robi Include. Jeśli użyjesz Include twoja własność nawigacji zostanie załadowana razem z główną encją.

Korzystanie z leniwego ładowania i szybkiego ładowania zależy od potrzeb, a także od wydajności. Include ładuje wszystkie dane w pojedynczej kwerendzie bazy danych, ale może to spowodować huge data set podczas używania wielu elementów lub ładowania wielu elementów. Jeśli masz pewność, że do przetworzenia będziesz potrzebował Brand i wszystkich Products, powinieneś użyć szybkiego ładowania.

Leniwe ładowanie jest z kolei używane, jeśli nie masz pewności, której usługi nawigacji będziesz potrzebować. Na przykład, jeśli załadujesz 100 marek, ale będziesz musiał uzyskać dostęp tylko do produktów z jednej marki, nie jest konieczne ładowanie produktów dla wszystkich marek we wstępnym zapytaniu. Wadą leniwego ładowania jest osobne zapytanie (obietnica bazy danych) dla każdej właściwości nawigacji => jeśli załadujesz 100 marek bez uwzględnienia i uzyskasz dostęp do właściwości Products w każdej instancjiTwój kod wygeneruje kolejne 100 zapytań do wypełnienia tych właściwości nawigacyjnych = chętnych ładowanie używałoby tylko kwerendy singe, ale leniwy ładunek używał 101 zapytań (nazywa się to problemem N + 1).

W bardziej złożonych scenariuszach można zauważyć, że żadna z tych strategii nie działa tak, jak tego potrzebujesz, a do załadowania marek można zastosować trzecią strategię o nazwie ładowanie jawne lub osobne zapytania, a następnie produkty dla wszystkich potrzebnych marek.

Explicit ładowanie ma podobne wady jak leniwy załadunku, ale trzeba go wywołać ręcznie:

context.Entry(brand).Collection(b => b.Products).Load(); 

Główne korzyści dla wyraźnej załadunkiem jest możliwość filtrowania relację. Możesz użyć Query() przed Load() i użyć dowolnego filtrowania lub nawet chętnego ładowania relacji zagnieżdżonych.

+3

Czuję, że ta odpowiedź jest zwięzła i kompletna ... Dzięki. Polecono "Ładowanie powiązanych danych" http://msdn.microsoft.com/en-us/magazine/hh205756.aspx – Lijo

+0

Dziękuję za odpowiedź. Wciąż pomaga mi w 2016 roku. I mam jeszcze jedno pytanie: Czy istnieje sposób na to, aby zawsze chętniej ładować wszystkie właściwości w jednym wywołaniu? Ponieważ istnieją sytuacje, w których modele mają wiele właściwości nawigacyjnych i muszą być ładowane za każdym razem. – anuith

Powiązane problemy