Jakie efekty może mieć wirtualne słowo kluczowe w kodzie POCO Entity Framework 4.1?

229

Czy virtualsłowo kluczowe ma wpływ, gdy jest używane we właściwościach kodu EF Najpierw ?. Czy ktoś może opisać wszystkie jego konsekwencje w różnych sytuacjach?

Na przykład wiem, że może kontrolować leniwe ładowanie - jeśli użyjesz wirtualnego słowa kluczowego we właściwości relacji ICollection / jeden do wielu, domyślnie zostanie on załadowany leniwie, a jeśli pozostawisz wirtualne słowo kluczowe, to będzie być chętnym.

Jakie inne efekty może virtualmieć słowo kluczowe w EF z jednostkami POCO ?. Czy powinienem ustawić domyślną opcję używania virtualwe wszystkich moich właściwościach, czy też domyślną opcję nieużywania?

Scott Stafford
źródło

Odpowiedzi:

194

Jak dotąd znam te efekty.

  • Leniwe ładowanie : Wszelkie virtualICollection będą ładowane leniwie, chyba że zaznaczysz je inaczej.
  • Bardziej wydajne śledzenie zmian . Jeśli spełniasz wszystkie poniższe wymagania, możesz śledzić zmiany za pomocą bardziej wydajnej metody, podpinając swoje właściwości wirtualne. Z linku:

    Aby uzyskać proxy do śledzenia zmian, podstawową zasadą jest, że twoja klasa musi być publiczna, nieabstrakcyjna lub nie zapieczętowana. Twoja klasa musi także implementować publiczne wirtualne moduły pobierające / ustawiające dla wszystkich trwałych właściwości. Na koniec musisz zadeklarować właściwości nawigacji relacji oparte na kolekcji jako ICollection<T>tylko. Nie mogą być konkretną implementacją ani innym interfejsem, który się z nich wywodzi ICollection<T>(różnica w porównaniu z proxy odroczonego ładowania)

Innym przydatnym linkiem opisującym to są wymagania MSDN dotyczące tworzenia proxy POCO .

Scott Stafford
źródło
52
Nie ma innego powodu, aby uczynić właściwości wirtualnymi. Właściwości nawigacyjne są oznaczone jako wirtualne dla leniwego ładowania, a właściwości skalarne są oznaczone jako wirtualne dla śledzenia zmian.
Ladislav Mrnka
10
czym są właściwości nawigacji i jakie są właściwości skalarne?
Abid Ali,
9
@AbidAli: Uważam, że właściwość nawigacji jest kluczem obcym (typ klasy encji) lub relacją jeden do wielu (typu ICollection <>). Właściwością skalarną jest typ podstawowy (int, string, ..) lub ComplexType (który jest po prostu strukturą typów podstawowych).
Scott Stafford,
2
Czy public virtual byte[] bigData { get; set; }ładowanie jest opóźnione?
AechoLiu
9
bajty [] będą chętnie ładowane, tylko klucze obce mogą być leniwe. Jeśli nie chcesz pobierać tej kolumny, nigdy nie pobieraj całego rekordu - po prostu .Select(a=>new { fields you want }).
Scott Stafford,
63

To wirtualne słowo kluczowe jest powiązane z tematem ładowania danych z frameworku encji (leniwe ładowanie, szybkie ładowanie i jawne ładowanie).

Powinieneś używać wirtualnego słowa kluczowego, gdy chcesz ładować dane z opóźnionym ładowaniem.

leniwe ładowanie to proces, w którym jednostka lub zbiór jednostek jest automatycznie ładowany z bazy danych przy pierwszym dostępie.

Na przykład podczas korzystania z klasy encji Blog zdefiniowanej poniżej powiązane posty zostaną załadowane przy pierwszym otwarciu właściwości nawigacji Posty:

public class Blog 
{  
     public int BlogId { get; set; }  
     public string Name { get; set; }  
     public string Url { get; set; }  
     public string Tags { get; set; }  
     public virtual ICollection<Post> Posts { get; set; }  
}

Leniwe ładowanie kolekcji Postów można wyłączyć, ustawiając właściwość Posty na inną niż wirtualna.

jeśli leniwe ładowanie jest wyłączone, ładowanie kolekcji Postów nadal można osiągnąć przy użyciu szybkiego ładowania (przy użyciu metody Uwzględnij) lub jawnego ładowania powiązanych obiektów (przy użyciu metody Ładuj).

Chętnie ładuję:

using (var context = new BloggingContext()) 
{ 
    // Load all blogs and related posts 
    var blogs1 = context.Blogs 
                          .Include(b => b.Posts) 
                          .ToList(); 
}

Jawne ładowanie:

using (var context = new BloggingContext()) 
{ 
    var blog = context.Blogs.Find(1); 

    // Load the posts related to a given blog 
    context.Entry(blog).Collection(p => p.Posts).Load(); 
}
Parsa
źródło
1
Jak uniknąć problemu N + 1 podczas korzystania z wirtualnego (leniwe ładowanie)? Na przykład context.Blogs.ToList (); wtedy nie dołączy do tabel i uruchomi wybrane zapytanie tak samo, jak liczba blogów.
Ekspert chce być
1
@Expertwannabe Nawet jeśli używasz leniwego ładowania, nadal możesz jawnie poprosić o niecierpliwy ładunek z wezwaniem do Include().
Monsignor