W następującym blogu: http://weblogs.asp.net/scottgu/archive/2010/07/16/code-first-development-with-entity-framework-4.aspx
Blog zawiera następujący przykładowy kod:
public class Dinner
{
public int DinnerID { get; set; }
public string Title { get; set; }
public DateTime EventDate { get; set; }
public string Address { get; set; }
public string HostedBy { get; set; }
public virtual ICollection<RSVP> RSVPs { get; set; }
}
public class RSVP
{
public int RsvpID { get; set; }
public int DinnerID { get; set; }
public string AttendeeEmail { get; set; }
public virtual Dinner Dinner { get; set; }
}
Jaki jest cel użycia virtual
podczas definiowania właściwości w klasie? Jaki to ma wpływ?
c#
class
properties
virtual
Gary Jones
źródło
źródło
Odpowiedzi:
Pozwala Entity Framework na utworzenie proxy wokół wirtualnej właściwości, aby ta właściwość mogła obsługiwać leniwe ładowanie i bardziej wydajne śledzenie zmian. Zobacz Jakie efekty może mieć wirtualne słowo kluczowe w kodzie POCO Entity Framework 4.1? dla dokładniejszej dyskusji.
Edytuj, aby wyjaśnić „utwórz proxy wokół”: Poprzez „utwórz proxy wokół” Mam na myśli konkretnie to, co robi Entity Framework. Entity Framework wymaga, aby twoje właściwości nawigacyjne były oznaczone jako wirtualne, aby obsługiwane było opóźnione ładowanie i efektywne śledzenie zmian. Zobacz Wymagania dotyczące tworzenia proxy POCO .
Entity Framework wykorzystuje dziedziczenie do obsługi tej funkcji, dlatego wymaga, aby niektóre właściwości były oznaczone wirtualnie w POCO klasy podstawowej. Dosłownie tworzy nowe typy, które wywodzą się z typów POCO. Zatem Twoje POCO działa jako typ podstawowy dla dynamicznie tworzonych podklas Entity Framework. Właśnie to miałem na myśli mówiąc „utwórz proxy”.
Dynamicznie tworzone podklasy tworzone przez Entity Framework stają się widoczne, gdy używa się Entity Framework w czasie wykonywania, a nie w czasie kompilacji statycznej. I tylko jeśli włączysz leniwe ładowanie lub zmianę funkcji śledzenia w Entity Framework. Jeśli zdecydujesz się nigdy nie używać leniwych funkcji ładowania lub zmiany śledzenia Entity Framework (co nie jest ustawieniem domyślnym), nie musisz deklarować żadnych właściwości nawigacji jako wirtualnych. Następnie jesteś odpowiedzialny za samodzielne ładowanie tych właściwości nawigacji, albo za pomocą tego, co Entity Framework określa jako „chętne ładowanie”, lub za ręczne wyszukiwanie powiązanych typów w wielu zapytaniach do bazy danych. Możesz i powinieneś używać leniwych funkcji ładowania i zmiany śledzenia dla swoich właściwości nawigacyjnych w wielu scenariuszach.
Jeśli miałbyś stworzyć samodzielną klasę i oznaczyć właściwości jako wirtualne, a także po prostu skonstruować i użyć instancji tych klas we własnej aplikacji, całkowicie poza zakresem Entity Framework, to twoje wirtualne właściwości nie zyskałyby nic na ich posiadać.
Edytuj, aby opisać, dlaczego właściwości mają być oznaczone jako wirtualne
Właściwości takie jak:
Nie są polami i nie powinny być traktowane jako takie. Są to tak zwane metody pobierające i ustawiające, aw czasie kompilacji są konwertowane na metody.
Dlatego są oznaczone jako wirtualne do użytku w Entity Framework, pozwala dynamicznie tworzonym klasom przesłonić wewnętrznie generowane
get
iset
funkcje. Jeśli narzędzie pobierające / ustawiające właściwości nawigacji działa dla Ciebie w ramach korzystania z Entity Framework, spróbuj zmienić je tak, aby zawierały tylko właściwości, rekompiluj i sprawdź, czy Entity Framework jest w stanie nadal poprawnie działać:źródło
Słowo
virtual
kluczowe w języku C # umożliwia zastąpienie metody lub właściwości przez klasy potomne. Aby uzyskać więcej informacji, zapoznaj się z dokumentacją MSDN słowa kluczowego „virtual”AKTUALIZACJA: To nie odpowiada na pytanie, jakie jest obecnie zadawane, ale zostawię to tutaj każdemu, kto szuka prostej odpowiedzi na pierwotne , nieopisowe pytanie.
źródło
virtual
nieruchomościami za pomocą Entity Framework - nawet jeśli nie jest to wyraźnie określone w tytule OP. Przyjęta odpowiedź jest taka, ponieważ dotyczy ona elementów Entity Framework oraz tego, w jaki sposób / dlaczegovirtual
właściwości są używane w tym kontekście.Rozumiem frustrację PO, to użycie wirtualnego nie jest przeznaczone do szablonowej abstrakcji, na którą działa modyfikator wirtualny defacto.
Jeśli ktoś nadal ma z tym problem, oferuję punkt widzenia, ponieważ staram się, aby rozwiązania były proste, a żargon minimalny:
Entity Framework w prostym kawałku wykorzystuje leniwe ładowanie, co jest odpowiednikiem przygotowania czegoś do przyszłego wykonania. To pasuje do modyfikatora „wirtualnego”, ale jest coś więcej.
W Entity Framework użycie wirtualnej właściwości nawigacji pozwala oznaczyć ją jako odpowiednik dopuszczalnego klucza obcego w SQL. Nie musisz chętnie dołączać do każdej tabeli z kluczami podczas wykonywania zapytania, ale kiedy potrzebujesz informacji - staje się to zależne od zapotrzebowania.
Wspomniałem również o wartości zerowej, ponieważ wiele właściwości nawigacji nie jest na początku istotnych. tzn. w scenariuszu klienta / Zamówienia nie trzeba czekać do momentu przetworzenia zamówienia, aby utworzyć klienta. Możesz, ale jeśli miałeś wieloetapowy proces, aby to osiągnąć, możesz potrzebować trwać dane klienta do późniejszego zakończenia lub do wdrożenia przyszłych zamówień. Jeśli wszystkie właściwości nawigacji zostałyby zaimplementowane, trzeba będzie ustanowić każde pole klucza obcego i pole relacyjne w składowaniu. To naprawdę po prostu przywraca dane do pamięci, co eliminuje rolę trwałości.
Chociaż może się to wydawać tajemnicze w rzeczywistym wykonaniu w czasie wykonywania, znalazłem najlepszą praktyczną zasadę: jeśli wysyłasz dane (wczytujesz do View Model lub Serializable Model) i potrzebujesz wartości przed referencjami, nie rób używać wirtualnego; Jeśli twój zakres zbiera dane, które mogą być niekompletne lub wymagają wyszukiwania i nie wymagają uzupełnienia każdego parametru wyszukiwania, kod dobrze wykorzysta odwołanie, podobnie jak użycie właściwości wartości zerowej int? długie?. Ponadto, abstrahując logikę biznesową od gromadzenia danych, dopóki nie trzeba jej wstrzykiwać, ma wiele korzyści związanych z wydajnością, podobnie jak tworzenie instancji obiektu i rozpoczynanie go od zera. Entity Framework wykorzystuje wiele refleksji i dynamiki, które mogą obniżyć wydajność, a potrzeba posiadania elastycznego modelu, który można skalować do zapotrzebowania, ma kluczowe znaczenie dla zarządzania wydajnością.
Dla mnie zawsze miało to większy sens niż używanie przeciążonego żargonu technologicznego, takiego jak serwery proxy, delegaci, osoby obsługujące i tym podobne. Gdy uderzysz w swój trzeci lub czwarty język programowania, może się z nimi bałaganić.
źródło
Z książki „ASP.NET MVC 5 z Bootstrap i Knockout.js”
źródło
W kontekście EF oznaczenie właściwości jako wirtualnej umożliwia EF użycie opóźnionego ładowania do załadowania. Aby leniwe ładowanie działało, EF musi utworzyć obiekt proxy, który przesłania właściwości wirtualne, za pomocą implementacji, która ładuje obiekt, do którego istnieje odwołanie, przy pierwszym dostępie. Jeśli nie oznaczysz właściwości jako wirtualnej, leniwe ładowanie nie będzie z nią działać.
źródło
Wirtualne słowo kluczowe służy do modyfikowania metody, właściwości, indeksatora lub deklaracji zdarzenia i umożliwia zastąpienie go w klasie pochodnej. Na przykład tę metodę można zastąpić dowolną dziedziczącą klasą:
źródło
Nie możemy rozmawiać o wirtualnych członkach bez odwoływania się do polimorfizmu . W rzeczywistości funkcja, właściwość, indeksator lub zdarzenie w klasie bazowej oznaczonej jako wirtualna pozwoli zastąpić klasę pochodną.
Domyślnie członkowie klasy nie są wirtualni i nie można ich oznaczyć jako modyfikatory statyczne, abstrakcyjne, prywatne lub zastępujące.
Przykład Rozważmy metodę ToString () w System.Object . Ponieważ ta metoda jest członkiem System.Object, jest dziedziczona we wszystkich klasach i zapewni metody ToString () wszystkim.
Dane wyjściowe poprzedniego kodu to:
Rozważmy, że chcemy zmienić standardowe zachowanie metod ToString () odziedziczonych z System.Object w naszej klasie Company. Aby osiągnąć ten cel, wystarczy użyć słowa kluczowego override, aby zadeklarować kolejną implementację tej metody.
Teraz, gdy wywoływana jest metoda wirtualna, środowisko wykonawcze sprawdzi, czy istnieje nadrzędny element w klasie pochodnej i wywoła ją, jeśli jest obecna. Dane wyjściowe naszej aplikacji będą wówczas:
W rzeczywistości, jeśli zaznaczysz klasę System.Object, przekonasz się, że metoda jest oznaczona jako wirtualna.
źródło