Objectidentiteit
Objecten in de runtime hebben unieke identiteiten. Twee variabelen die naar hetzelfde object verwijzen, verwijzen eigenlijk naar hetzelfde exemplaar van het object. Vanwege dit feit zijn wijzigingen die u via een pad door de ene variabele aanbrengt, onmiddellijk zichtbaar via de andere.
Rijen in een relationele databasetabel hebben geen unieke identiteiten. Omdat elke rij een unieke primaire sleutel heeft, delen geen twee rijen dezelfde sleutelwaarde. Dit feit beperkt echter alleen de inhoud van de databasetabel.
In werkelijkheid worden gegevens het vaakst uit de database gehaald en in een andere laag gebracht, waarbij een toepassing ermee werkt. Dit is het model dat LINQ naar SQL ondersteunt. Wanneer gegevens uit de database worden gehaald als rijen, hebt u geen verwachting dat twee rijen die dezelfde gegevens vertegenwoordigen, daadwerkelijk overeenkomen met dezelfde rijexemplaren. Als u twee keer een query uitvoert op een specifieke klant, krijgt u twee rijen met gegevens. Elke rij bevat dezelfde informatie.
Met objecten verwacht u iets heel anders. U verwacht dat als u herhaaldelijk om dezelfde informatie vraagt DataContext , u in feite hetzelfde objectexemplaren krijgt. U verwacht dit gedrag omdat objecten speciale betekenis hebben voor uw toepassing en u verwacht dat ze zich gedragen als objecten. U hebt ze ontworpen als hiërarchieën of grafieken. U verwacht ze als zodanig op te halen en niet meerdere gerepliceerde exemplaren te ontvangen, alleen omdat u meerdere keer om hetzelfde hebt gevraagd.
In LINQ naar SQL beheert de DataContext objectidentiteit. Wanneer u een nieuwe rij ophaalt uit de database, wordt de rij vastgelegd in een identiteitstabel met de primaire sleutel en wordt er een nieuw object gemaakt. Wanneer u dezelfde rij ophaalt, wordt het oorspronkelijke objectexemplaren teruggegeven aan de toepassing. Op deze manier vertaalt het DataContext concept van identiteit zoals gezien door de database (dat wil gezegd primaire sleutels) in het concept van identiteit dat wordt gezien door de taal (dat wil gezegd, instanties). De toepassing ziet alleen het object in de status dat het voor het eerst is opgehaald. De nieuwe gegevens, indien anders, worden verwijderd. Zie Objecten ophalen uit de identiteitscache voor meer informatie.
LINQ naar SQL gebruikt deze benadering om de integriteit van lokale objecten te beheren om optimistische updates te ondersteunen. Omdat de enige wijzigingen die optreden nadat het object voor het eerst is gemaakt, de wijzigingen zijn die door de toepassing zijn aangebracht, is de intentie van de toepassing duidelijk. Als er in de tussentijd wijzigingen door een externe partij zijn opgetreden, worden deze op het moment SubmitChanges()
aangeroepen.
Notitie
Als het object dat door de query is aangevraagd, gemakkelijk kan worden geïdentificeerd als een object dat al is opgehaald, wordt er geen query uitgevoerd. De identiteitstabel fungeert als een cache van alle eerder opgehaalde objecten.
Voorbeelden
Voorbeeld van objectcaching 1
Als u in dit voorbeeld dezelfde query twee keer uitvoert, ontvangt u elke keer een verwijzing naar hetzelfde object in het geheugen.
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()
Voorbeeld van objectcaching 2
Als u in dit voorbeeld verschillende query's uitvoert die dezelfde rij retourneren uit de database, ontvangt u elke keer een verwijzing naar hetzelfde object in het geheugen.
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