Retrieving Objects from the Identity Cache

This topic describes the types of LINQ to SQL queries that return an object from the identity cache that is managed by the DataContext.

In LINQ to SQL, one of the ways in which the DataContext manages objects is by logging object identities in an identity cache as queries are executed. In some cases, LINQ to SQL will attempt to retrieve an object from the identity cache before executing a query in the database.

In general, for a LINQ to SQL query to return an object from the identity cache, the query must be based on the primary key of an object and must return a single object. In particular, the query must be in one of the general forms shown below.

Note

Pre-compiled queries will not return objects from the identity cache. For more information about pre-compiled queries, see CompiledQuery and How to: Store and Reuse Queries.

A query must be in one of the following general forms to retrieve an object from the identity cache:

In these general forms, Function1, Function2, and predicate are defined as follows.

Function1 can be any of the following:

Function2 can be any of the following:

predicate must be an expression in which the object's primary key property is set to a constant value. If an object has a primary key defined by more than one property, each primary key property must be set to a constant value. The following are examples of the form predicate must take:

  • c => c.PK == constant_value

  • c => c.PK1 == constant_value1 && c=> c.PK2 == constant_value2

Example

The following code provides examples of the types of LINQ to SQL queries that retrieve an object from the identity cache.

NorthwindDataContext context = new NorthwindDataContext();

// This query does not retrieve an object from
// the query cache because it is the first query.
// There are no objects in the cache.
var a = context.Customers.First();
Console.WriteLine("First query gets customer {0}. ", a.CustomerID);

// This query returns an object from the query cache.
var b = context.Customers.Where(c => c.CustomerID == a.CustomerID);
foreach (var customer in b )
{
    Console.WriteLine(customer.CustomerID);
}

// This query returns an object from the identity cache.
// Note that calling FirstOrDefault(), Single(), or SingleOrDefault()
// instead of First() will also return an object from the cache.
var x = context.Customers.
    Where(c => c.CustomerID == a.CustomerID).
    First();
Console.WriteLine(x.CustomerID);

// This query returns an object from the identity cache.
// Note that calling FirstOrDefault(), Single(), or SingleOrDefault()
// instead of First() (each with the same predicate) will also
// return an object from the cache.
var y = context.Customers.First(c => c.CustomerID == a.CustomerID);
Console.WriteLine(y.CustomerID);
Dim context As New NorthwindDataContext()

' This query does not retrieve an object from
' the query cache because it is the first query.
' There are no objects in the cache. 
Dim a = context.Customers.First()
Console.WriteLine("First query gets customer {0}. ", a.CustomerID)

' This query returns an object from the query cache.
Dim b = context.Customers.Where(Function(c) c.CustomerID = a.CustomerID)
For Each customer In b
    Console.WriteLine(customer.CustomerID)
Next

' This query returns an object from the identity cache.
' Note that calling FirstOrDefault(), Single(), or SingleOrDefault()
' instead of First() will also return an object from the cache.
Dim x = context.Customers. _
    Where(Function(c) c.CustomerID = a.CustomerID). _
    First()
Console.WriteLine(x.CustomerID)

' This query returns an object from the identity cache.
' Note that calling FirstOrDefault(), Single(), or SingleOrDefault()
' instead of First() (each with the same predicate) will also
' return an object from the cache.
Dim y = context.Customers.First(Function(c) c.CustomerID = a.CustomerID)
Console.WriteLine(y.CustomerID)

See also