Objektidentität (LINQ to SQL)
Aktualisiert: November 2007
Objekte verfügen zur Laufzeit über eindeutige Identitäten. Zwei Variablen, die sich auf das gleiche Objekt beziehen, verweisen tatsächlich auf die gleiche Objektinstanz. Aufgrund dieser Tatsache sind Änderungen, die Sie über einen Pfad durch eine Variable vornehmen, sofort über die andere Variable sichtbar.
Zeilen in einer relationalen Datenbanktabelle weisen keine eindeutigen Identitäten auf. Da jede Zeile über einen eindeutigen Primärschlüssel verfügt, weisen keine zwei Zeilen den gleichen Schlüsselwert auf. Diese Tatsache schränkt jedoch nur den Inhalt der Datenbanktabelle ein.
Tatsächlich werden die Daten in der Regel aus der Datenbank in eine andere Kategorie abgerufen, von der aus sie durch eine Anwendung genutzt werden. Dies ist das von LINQ to SQL unterstützte Modell. Wenn Daten in Form von Zeilen aus der Datenbank abgerufen werden, können Sie nicht davon ausgehen, dass zwei Zeilen, die die gleichen Daten darstellen, tatsächlich der gleichen Zeileninstanz entsprechen. Wenn Sie einen bestimmten Kunden zweimal abrufen, erhalten Sie zwei Datenzeilen. Jede Zeile enthält die gleichen Informationen.
Von Objekten erwarten Sie etwas ganz anderes. Sie gehen davon aus, dass Sie bei wiederholtem Abrufen der gleichen Informationen aus dem DataContext tatsächlich die gleiche Objektinstanz erhalten. Sie erwarten dieses Verhalten, da Objekte für Ihre Anwendung von besonderer Bedeutung sind und weil Sie von einem objektgemäßen Verhalten ausgehen. Sie haben sie als Hierarchien oder Graphen 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 der DataContext die Objektidentität. Wenn Sie eine neue Zeile aus der Datenbank abrufen, wird diese mit ihrem Primärschlüssel in einer Identitätstabelle protokolliert, und es wird ein neues Objekt erstellt. Jedes Mal, wenn Sie die gleiche Zeile abrufen, wird die ursprüngliche Objektinstanz an die Anwendung zurückgegeben. Auf diese Weise übersetzt der DataContext das Identitätskonzept aus Sicht der Datenbank (Primärschlüssel) in das Identitätskonzept aus Sicht der Sprache (Instanzen). Die Anwendung sieht nur das Objekt in dem Zustand, in dem es zuerst abgerufen wurde. Die neuen Daten werden (sofern sie abweichen) verworfen.
LINQ to SQL verwendet diesen Ansatz zur Verwaltung der Integrität lokaler Objekte, um vollständige Aktualisierungen zu unterstützen. Da die einzigen Änderungen, die nach dem ersten Erstellen des Objekts auftreten, von der Anwendung vorgenommen werden, ist die Absicht der Anwendung klar. Sind zwischenzeitlich Änderungen durch eine externe Partei erfolgt, werden diese zum Zeitpunkt des Aufrufs von SubmitChanges() identifiziert.
Hinweis: |
---|
Lässt sich das von der Abfrage angeforderte Objekt leicht als bereits abgerufen identifizieren, wird keine Abfrage ausgeführt. Die Identitätstabelle dient als Cache für alle zuvor abgerufenen Objekte. |
Beispiele
Objektzwischenspeicherung, Beispiel 1
Wenn Sie in diesem Beispiel eine Abfrage zweimal ausführen, erhalten Sie stets einen Verweis auf das gleiche Objekt im Arbeitsspeicher.
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()
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();
Objektzwischenspeicherung, Beispiel 2
Wenn Sie in diesem Beispiel unterschiedliche Abfragen ausführen, die die gleiche Zeile aus der Datenbank zurückgeben, erhalten Sie stets einen Verweis auf das gleiche Objekt im Arbeitsspeicher.
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
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;