Im folgenden Blog: http://weblogs.asp.net/scottgu/archive/2010/07/16/code-first-development-with-entity-framework-4.aspx
Der Blog enthält das folgende Codebeispiel:
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; }
}
Was ist der Zweck virtual
beim Definieren einer Eigenschaft in einer Klasse? Welchen Effekt hat es?
c#
class
properties
virtual
Gary Jones
quelle
quelle
Antworten:
Damit kann das Entity Framework einen Proxy um die virtuelle Eigenschaft erstellen, sodass die Eigenschaft das verzögerte Laden und eine effizientere Änderungsverfolgung unterstützen kann. Siehe Welche Auswirkungen kann das virtuelle Schlüsselwort in Entity Framework 4.1 POCO Code First haben? für eine gründlichere Diskussion.
Bearbeiten, um zu verdeutlichen, dass "Proxy erstellen": Mit "Proxy erstellen" verweise ich speziell auf die Funktionen des Entity Framework. Für das Entity Framework müssen Ihre Navigationseigenschaften als virtuell markiert sein, damit ein verzögertes Laden und eine effiziente Änderungsverfolgung unterstützt werden. Siehe Anforderungen zum Erstellen von POCO-Proxys .
Das Entity Framework verwendet Vererbung, um diese Funktionalität zu unterstützen. Aus diesem Grund müssen bestimmte Eigenschaften in den POCOs Ihrer Basisklasse als virtuell markiert werden. Es werden buchstäblich neue Typen erstellt, die von Ihren POCO-Typen abgeleitet sind. Ihr POCO fungiert also als Basistyp für die dynamisch erstellten Unterklassen des Entity Framework. Das habe ich mit "Proxy erstellen" gemeint.
Die dynamisch erstellten Unterklassen, die das Entity Framework erstellt, werden deutlich, wenn das Entity Framework zur Laufzeit und nicht zur statischen Kompilierungszeit verwendet wird. Und nur, wenn Sie die Funktionen zum verzögerten Laden oder Ändern von Entity Framework aktivieren. Wenn Sie die Funktionen zum verzögerten Laden oder Ändern der Nachverfolgung des Entity Frameworks (die nicht die Standardeinstellung sind) niemals verwenden möchten, müssen Sie keine Ihrer Navigationseigenschaften als virtuell deklarieren. Sie sind dann dafür verantwortlich, diese Navigationseigenschaften selbst zu laden, indem Sie entweder das verwenden, was das Entity Framework als "eifriges Laden" bezeichnet, oder verwandte Typen manuell über mehrere Datenbankabfragen hinweg abrufen. In vielen Szenarien können und sollten Sie jedoch Funktionen zum verzögerten Laden und Ändern der Nachverfolgung für Ihre Navigationseigenschaften verwenden.
Wenn Sie eine eigenständige Klasse erstellen und Eigenschaften als virtuell markieren und einfach Instanzen dieser Klassen in Ihrer eigenen Anwendung erstellen und verwenden würden, die vollständig außerhalb des Bereichs des Entity Frameworks liegen, würden Ihre virtuellen Eigenschaften Ihnen nichts davon bringen besitzen.
Bearbeiten, um zu beschreiben, warum Eigenschaften als virtuell markiert werden
Eigenschaften wie:
Sind keine Felder und sollten nicht als solche betrachtet werden. Diese werden als Getter und Setter bezeichnet und zur Kompilierungszeit in Methoden konvertiert.
Aus diesem Grund werden sie für die Verwendung im Entity Framework als virtuell markiert. Dadurch können die dynamisch erstellten Klassen die intern generierten
get
undset
Funktionen überschreiben . Wenn Ihre Getter / Setter für Navigationseigenschaften in Ihrer Entity Framework-Verwendung für Sie arbeiten, versuchen Sie, sie auf Eigenschaften zu überarbeiten, neu zu kompilieren und zu überprüfen, ob das Entity Framework noch ordnungsgemäß funktioniert:quelle
Das
virtual
Schlüsselwort in C # ermöglicht das Überschreiben einer Methode oder Eigenschaft durch untergeordnete Klassen. Weitere Informationen finden Sie in der MSDN-Dokumentation zum Schlüsselwort 'virtual'UPDATE: Dies beantwortet die aktuell gestellte Frage nicht, aber ich lasse sie hier für alle, die nach einer einfachen Antwort auf die ursprüngliche , nicht beschreibende Frage suchen .
quelle
virtual
über Entity Framework mit Eigenschaften befassen - auch wenn dies im Titel von OP nicht explizit angegeben ist. Die akzeptierte Antwort ist so, weil sie die Entity Framework-Seite der Dinge berührt und wie / warumvirtual
Eigenschaften in diesem Kontext verwendet werden.Ich verstehe die Frustration der OP, diese Verwendung von virtuell ist nicht für die Vorlagenabstraktion gedacht, für die der virtuelle Modifikator defacto wirksam ist.
Wenn noch jemand damit zu kämpfen hat, würde ich meinen Standpunkt darlegen, da ich versuche, die Lösungen einfach und den Jargon auf ein Minimum zu beschränken:
Das Entity Framework in einem einfachen Teil verwendet das verzögerte Laden, was dem Vorbereiten von etwas für die zukünftige Ausführung entspricht. Das passt zum "virtuellen" Modifikator, aber dazu gehört noch mehr.
Wenn Sie in Entity Framework eine virtuelle Navigationseigenschaft verwenden, können Sie diese als Äquivalent eines nullbaren Fremdschlüssels in SQL bezeichnen. Sie MÜSSEN nicht eifrig jeder Schlüsseltabelle beitreten, wenn Sie eine Abfrage ausführen, aber wenn Sie die Informationen benötigen, werden sie bedarfsgesteuert.
Ich habe auch nullable erwähnt, da viele Navigationseigenschaften zunächst nicht relevant sind. dh In einem Kunden- / Bestellszenario müssen Sie nicht bis zu dem Moment warten, in dem eine Bestellung bearbeitet wird, um einen Kunden zu erstellen. Sie können, aber wenn Sie einen mehrstufigen Prozess hatte dies zu erreichen, können Sie die Notwendigkeit finden , beharren die Kundendaten für eine spätere Fertigstellung oder für die Bereitstellung auf zukünftige Aufträge. Wenn alle Nav-Eigenschaften implementiert wären, müssten Sie beim Speichern jeden Fremdschlüssel und jedes relationale Feld einrichten. Das setzt die Daten wirklich nur wieder in den Speicher zurück, was die Rolle der Persistenz zunichte macht.
Obwohl es in der tatsächlichen Ausführung zur Laufzeit kryptisch erscheint, habe ich festgestellt, dass die beste Faustregel lautet: Wenn Sie Daten ausgeben (in ein Ansichtsmodell oder ein serialisierbares Modell einlesen) und Werte vor Referenzen benötigen, tun Sie dies nicht benutze virtuell; Wenn in Ihrem Bereich Daten erfasst werden, die möglicherweise unvollständig sind oder gesucht werden müssen und nicht alle für eine Suche abgeschlossenen Suchparameter erforderlich sind, verwendet der Code die Referenz gut, ähnlich wie bei der Verwendung von Eigenschaften mit nullbaren Werten int? lange?. Das Abstrahieren Ihrer Geschäftslogik von Ihrer Datenerfassung bis zum Einfügen hat viele Leistungsvorteile, ähnlich wie das Instanziieren eines Objekts und das Starten bei Null. Entity Framework verwendet viel Reflexion und Dynamik, was die Leistung beeinträchtigen kann. Die Notwendigkeit eines flexiblen Modells, das an die Anforderungen angepasst werden kann, ist für die Verwaltung der Leistung von entscheidender Bedeutung.
Für mich war das immer sinnvoller als die Verwendung von überladenem Fachjargon wie Proxies, Delegierten, Handlern und dergleichen. Sobald Sie Ihre dritte oder vierte Programmiersprache erreicht haben, kann es mit diesen unordentlich werden.
quelle
Aus dem Buch "ASP.NET MVC 5 mit Bootstrap und Knockout.js"
quelle
Wenn Sie im Kontext von EF eine Eigenschaft als virtuell markieren, kann EF sie verzögert laden. Damit das verzögerte Laden funktioniert, muss EF ein Proxy-Objekt erstellen, das Ihre virtuellen Eigenschaften mit einer Implementierung überschreibt, die die referenzierte Entität beim ersten Zugriff lädt. Wenn Sie die Eigenschaft nicht als virtuell markieren, funktioniert das verzögerte Laden nicht.
quelle
Das virtuelle Schlüsselwort wird verwendet, um eine Methode, eine Eigenschaft, einen Indexer oder eine Ereignisdeklaration zu ändern und zu ermöglichen, dass sie in einer abgeleiteten Klasse überschrieben wird. Diese Methode kann beispielsweise von jeder Klasse überschrieben werden, die sie erbt:
quelle
Wir können nicht über virtuelle Mitglieder sprechen, ohne auf Polymorphismus Bezug zu nehmen . Tatsächlich ermöglicht eine Funktion, Eigenschaft, ein Indexer oder ein Ereignis in einer als virtuell gekennzeichneten Basisklasse das Überschreiben einer abgeleiteten Klasse.
Standardmäßig sind Mitglieder einer Klasse nicht virtuell und können nicht als solche gekennzeichnet werden, wenn statische, abstrakte, private oder Überschreibungsmodifikatoren verwendet werden.
Beispiel Betrachten wir die ToString () -Methode in System.Object . Da diese Methode Mitglied von System.Object ist, wird sie von allen Klassen geerbt und stellt allen die ToString () -Methoden zur Verfügung.
Die Ausgabe des vorherigen Codes lautet:
Angenommen, wir möchten das Standardverhalten der von System.Object in unserer Company-Klasse geerbten ToString () -Methoden ändern. Um dieses Ziel zu erreichen, reicht es aus, das Schlüsselwort override zu verwenden, um eine weitere Implementierung dieser Methode zu deklarieren.
Wenn nun eine virtuelle Methode aufgerufen wird, sucht die Laufzeit in ihrer abgeleiteten Klasse nach einem überschreibenden Mitglied und ruft es auf, falls vorhanden. Die Ausgabe unserer Anwendung lautet dann:
Wenn Sie die System.Object-Klasse überprüfen, werden Sie feststellen, dass die Methode als virtuell markiert ist.
quelle