LINQ to SQL Tutorial
Lesson 15 of 38 · Part 15 Identity Cache in Linq to SQL · Database
Part 15 Identity Cache in Linq to SQL
Text version of the video
http://csharp-video-tutorials.blogspot.com/2014/09/part-15-identity-cache-in-linq-to-sql.html
Slides
http://csharp-video-tutorials.blogspot.com/2014/09/part-15-identity-cache-in-linq-to-sql_21.html
LINQ to SQL Tutorial – All Text Articles & Slides
http://csharp-video-tutorials.blogspot.com/2014/09/linq-to-sql-tutorial.html
LINQ to SQL Tutorial Playlist
Dot Net, SQL, Angular, JavaScript, jQuery and Bootstrap complete courses
https://www.youtube.com/user/kudvenkat/playlists?view=1&sort=dd
In this video we will discuss what is Identity cache and it’s impact on Linq to SQL queries.
What is Identity Cache
DataContext object uses Identity Cache to manage objects. Let us understand this with an example.
References :
http://msdn.microsoft.com/en-us/library/vstudio/dd627203(v=vs.100).aspx
In this example, we are retrieving two students from the database with the same identity and using the the same datacontext object. With the first LINQ query is executed, it gets translated to T-SQL. The SQL query is executed and the result is brought back into the application, where a Student object is created. The object identity is stored in the Identity cache. When the second LINQ query is issued for the same student object, LINQ checks the identity cache and returns a reference to the student object that already exists. Notice that there is only one call to the database, inspite of having 2 linq queries. S1 and S2 are pointing to the same student object in memory.
using (SampleDataContext dbContext = new SampleDataContext())
{
dbContext.Log = Console.Out;
Student S1 = dbContext.Students.FirstOrDefault(x =] x.ID == 1);
Student S2 = dbContext.Students.FirstOrDefault(x =] x.ID == 1);
Console.WriteLine(“S1 == S2 : {0}”, object.ReferenceEquals(S1, S2));
}
Each instance of LINQ to SQL DataContext class has its own identity cache. This means if we have 2 different DataContext instances, and when we issue 2 linq queries 2 retrieve a student with the same identity, we get 2 different student objects back. S1 and S2 are two different objects in memory and registered in two different identity maps. Notice that the database also gets called 2 times.
using (SampleDataContext dbContext1 = new SampleDataContext())
using (SampleDataContext dbContext2 = new SampleDataContext())
{
dbContext1.Log = Console.Out;
dbContext2.Log = Console.Out;
Student S1 = dbContext1.Students.FirstOrDefault(x =] x.ID == 1);
Student S2 = dbContext2.Students.FirstOrDefault(x =] x.ID == 1);
Console.WriteLine(“S1 == S2 : {0}”, object.ReferenceEquals(S1, S2));
}
In this example we changed the FirstName of the student using the first datacontext object. We then called SubmitChanges() method, so the database has stored the new name for this student. However the student object for datacontext 2 still has the old name, because when we reissue the linq query for the same student object, this object is retrieved from the identity cache and not from the database. To have data retrieved from the database and to refresh the cache with updated values, we need to call the Refresh method of the second datacontext object.
using (SampleDataContext dbContext1 = new SampleDataContext())
using (SampleDataContext dbContext2 = new SampleDataContext())
{
dbContext1.Log = Console.Out;
dbContext2.Log = Console.Out;
Student S1 = dbContext1.Students.FirstOrDefault(x =] x.ID == 1);
Student S2 = dbContext2.Students.FirstOrDefault(x =] x.ID == 1);
Console.WriteLine(“S1.FirstName = {0}”, S1.FirstName);
Console.WriteLine(“S2.FirstName = {0}”, S2.FirstName);
S1.FirstName = “Updated…..”;
dbContext1.SubmitChanges();
Console.WriteLine(“FirstName updated…..”);
S2 = dbContext2.Students.FirstOrDefault(x =] x.ID == 1);
Console.WriteLine(“S1.FirstName = {0}”, S1.FirstName);
Console.WriteLine(“S2.FirstName = {0}”, S2.FirstName);
dbContext2.Refresh(System.Data.Linq.RefreshMode.OverwriteCurrentValues, S2);
Console.WriteLine(“After calling the refresh method”);
Console.WriteLine(“S1.FirstName = {0}”, S1.FirstName);
Console.WriteLine(“S2.FirstName = {0}”, S2.FirstName);
}