Freigeben über


Objektidentität

Objekte in der Laufzeit verfügen über eindeutige Identitäten. Zwei Variablen, die auf dasselbe Objekt verweisen, beziehen sich tatsächlich auf dieselbe Instanz des Objekts. Aufgrund dieser Tatsache werden Änderungen, die Sie über einen Pfad durch eine Variable vornehmen, sofort durch die andere sichtbar.

Zeilen in einer relationalen Datenbanktabelle weisen keine eindeutigen Identitäten auf. Da jede Zeile über einen eindeutigen Primärschlüssel verfügt, verwenden keine zwei Zeilen denselben Schlüsselwert. Diese Tatsache schränkt jedoch nur den Inhalt der Datenbanktabelle ein.

Tatsächlich werden Daten am häufigsten aus der Datenbank und in eine andere Ebene gebracht, in der eine Anwendung damit arbeitet. Dies ist das Modell, das LINQ to SQL unterstützt. Wenn Daten aus der Datenbank als Zeilen herausgebracht werden, erwarten Sie nicht, dass zwei Zeilen, die die gleichen Daten darstellen, tatsächlich denselben Zeileninstanzen entsprechen. Wenn Sie zwei Mal nach einem bestimmten Kunden fragen, erhalten Sie zwei Datenzeilen. Jede Zeile enthält dieselben Informationen.

Bei Objekten erwarten Sie etwas ganz anderes. Sie gehen davon aus, dass, wenn Sie die DataContext um die gleichen Informationen wiederholt bitten, Sie tatsächlich dieselbe Objektinstanz erhalten. Sie erwarten dieses Verhalten, da Objekte für Ihre Anwendung eine besondere Bedeutung haben und erwarten, dass sie sich wie Objekte verhalten. Sie haben sie als Hierarchien oder Diagramme entworfen. Sie möchten diese Objekte als solche abrufen und keine mehrfach replizierten Instanzen erhalten, nur weil Sie die gleichen Informationen mehrfach abrufen.

In LINQ to SQL verwaltet die DataContext Objektidentität. Wenn Sie eine neue Zeile aus der Datenbank abrufen, wird die Zeile anhand des Primärschlüssels in einer Identitätstabelle protokolliert, und ein neues Objekt wird erstellt. Immer wenn Sie dieselbe Zeile abrufen, wird die ursprüngliche Objektinstanz an die Anwendung zurückgegeben. Auf diese Weise übersetzt das DataContext das Konzept der Identität, wie sie in der Datenbank gesehen wird (d. h. Primärschlüssel), in das Konzept der Identität, wie sie von der Sprache gesehen wird (d. h. Instanzen). Die Anwendung sieht nur das Objekt im Zustand, in dem es zuerst abgerufen wurde. Die neuen Daten werden, falls sie unterschiedlich sind, ignoriert. Weitere Informationen finden Sie unter Abrufen von Objekten aus dem Identitätscache.

LINQ to SQL verwendet diesen Ansatz, um die Integrität lokaler Objekte zu verwalten, um optimistische Updates zu unterstützen. Da die einzigen Änderungen, die nach der ersten Erstellung des Objekts auftreten, diejenigen sind, die von der Anwendung vorgenommen werden, ist die Absicht der Anwendung eindeutig. Sind zwischenzeitlich Änderungen durch eine externe Partei erfolgt, werden diese zum Zeitpunkt des Aufrufs von SubmitChanges() identifiziert.

Hinweis

Wenn das von der Abfrage angeforderte Objekt leicht als bereits abgerufenes Objekt identifiziert werden kann, wird keine Abfrage ausgeführt. Die Identitätstabelle fungiert als Cache aller zuvor abgerufenen Objekte.

Beispiele

Objektzwischenspeicherung (Beispiel 1)

Wenn Sie in diesem Beispiel zweimal dieselbe Abfrage ausführen, erhalten Sie jedes Mal einen Verweis auf dasselbe Objekt im Arbeitsspeicher.

Customer cust1 =
    (from cust in db.Customers
     where cust.CustomerID == "BONAP"
     select cust).First();

Customer cust2 =
    (from cust in db.Customers
     where cust.CustomerID == "BONAP"
     select cust).First();
Dim cust1 As Customer = _
    (From cust In db.Customers _
     Where cust.CustomerID = "BONAP" _
     Select cust).First()

Dim cust2 As Customer = _
    (From cust In db.Customers _
     Where cust.CustomerID = "BONAP" _
     Select cust).First()

Objekt-Caching Beispiel 2

Wenn Sie in diesem Beispiel unterschiedliche Abfragen ausführen, die dieselbe Zeile aus der Datenbank zurückgeben, erhalten Sie jedes Mal einen Verweis auf dasselbe Objekt im Arbeitsspeicher.

Customer cust1 =
    (from cust in db.Customers
     where cust.CustomerID == "BONAP"
     select cust).First();

Customer cust2 =
    (from ord in db.Orders
     where ord.Customer.CustomerID == "BONAP"
     select ord).First().Customer;
Dim cust1 As Customer = _
    (From cust In db.Customers _
     Where cust.CustomerID = "BONAP" _
     Select cust).First()

Dim cust2 As Customer = _
    (From ord In db.Orders _
     Where ord.Customer.CustomerID = "BONAP" _
     Select ord).First().Customer

Siehe auch