When we wrote LINQ in Action, we took a bit of time to explain how the identity tracking system worked with LINQ to SQL to make sure that changed objects were retained when subsequent queries are requested from a data context. In a nutshell, when you issue a query, the data context translates the LINQ query into TSQL and sends that to the database. The database returns the rowsets to LINQ to SQL. The provider checks the returned rows against those that it is already tracking from previous fetches and, rather than instantiating the object again, returns the object in its internal store. This is done primarily to ensure that changes a user has made in the course of his context's lifetime are retained rather than being overwritten.
We also discussed (p. 258 if you're following along) how there is a special optimization wherein if you are querying for a single result, the pipeline would check the internal cache first before looking at the database, thus reducing the overhead of repeated hits to the database. An astute reader checked out our claim, and sure enough that optimization did not make it into the RTM bits of VS 2008. We considered fixing this in the second printing, but consulted with the product teams first. It turns out that the intended behavior was indeed to include this optimization, but due to a last minute bug, it didn't make it in.
As Dinesh points out, this oversight has been fixed in SP1. Now, if you try to fetch a single object (using Single, SingleOrDefault, First, or FirstOrDefault), the in memory object cache will be checked based on the identity columns declared in the entity's structure. If a matching object is found, it will be returned, otherwise the record will be requested from the database.