public void TestInsertingDataIntoTheSameTableShouldInvalidateTheCacheAutomatically() { using (var context = new SampleContext()) { var isActive = true; var name = "Product1"; var databaseLog = new StringBuilder(); context.Database.Log = commandLine => { databaseLog.AppendLine(commandLine); Trace.Write(commandLine); }; Trace.WriteLine("1st query, reading from db"); var debugInfo1 = new EFCacheDebugInfo(); var list1 = context.Products.Include(x => x.Tags) .OrderBy(product => product.ProductNumber) .Where(product => product.IsActive == isActive && product.ProductName == name) .Cacheable(debugInfo1) .ToList(); var sqlCommands = databaseLog.ToString().Trim(); Assert.AreEqual(false, string.IsNullOrWhiteSpace(sqlCommands)); Assert.AreEqual(false, debugInfo1.IsCacheHit); Assert.IsTrue(list1.Any()); Trace.WriteLine("same query, reading from 2nd level cache"); databaseLog.Clear(); var debugInfo2 = new EFCacheDebugInfo(); var list2 = context.Products.Include(x => x.Tags) .OrderBy(product => product.ProductNumber) .Where(product => product.IsActive == isActive && product.ProductName == name) .Cacheable(debugInfo2) .ToList(); sqlCommands = databaseLog.ToString().Trim(); Assert.AreEqual(true, string.IsNullOrWhiteSpace(sqlCommands)); Assert.AreEqual(true, debugInfo2.IsCacheHit); Assert.IsTrue(list2.Any()); Trace.WriteLine("inserting data, invalidates the cache on SaveChanges"); var rnd = new Random(); var newProduct = new Product { IsActive = false, ProductName = "Product" + rnd.Next(), ProductNumber = rnd.Next().ToString(), Notes = "Notes ...", UserId = 1 }; context.Products.Add(newProduct); context.SaveChanges(); Trace.WriteLine("same query after insert, reading from database."); databaseLog.Clear(); var debugInfo3 = new EFCacheDebugInfo(); var list3 = context.Products.Include(x => x.Tags) .OrderBy(product => product.ProductNumber) .Where(product => product.IsActive == isActive && product.ProductName == name) .Cacheable(debugInfo3) .ToList(); sqlCommands = databaseLog.ToString().Trim(); Assert.AreEqual(false, string.IsNullOrWhiteSpace(sqlCommands)); Assert.AreEqual(false, debugInfo3.IsCacheHit); Assert.IsTrue(list3.Any()); } }
public void TestTransactionRollbackShouldNotInvalidateTheCacheDependencyAutomatically() { using (var context = new SampleContext()) { var isActive = true; var name = "Product1"; var databaseLog = new StringBuilder(); context.Database.Log = commandLine => { databaseLog.AppendLine(commandLine); Trace.Write(commandLine); }; Trace.WriteLine("1st query, reading from db."); var debugInfo1 = new EFCacheDebugInfo(); var list1 = context.Products.Include(x => x.Tags) .OrderBy(product => product.ProductNumber) .Where(product => product.IsActive == isActive && product.ProductName == name) .Cacheable(debugInfo1) .ToList(); var sqlCommands = databaseLog.ToString().Trim(); Assert.AreEqual(false, string.IsNullOrWhiteSpace(sqlCommands)); Assert.AreEqual(false, debugInfo1.IsCacheHit); Assert.IsTrue(list1.Any()); Trace.WriteLine("same query, reading from 2nd level cache."); databaseLog.Clear(); var debugInfo2 = new EFCacheDebugInfo(); var list2 = context.Products.Include(x => x.Tags) .OrderBy(product => product.ProductNumber) .Where(product => product.IsActive == isActive && product.ProductName == name) .Cacheable(debugInfo2) .ToList(); sqlCommands = databaseLog.ToString().Trim(); Assert.AreEqual(true, string.IsNullOrWhiteSpace(sqlCommands)); Assert.AreEqual(true, debugInfo2.IsCacheHit); Assert.IsTrue(list2.Any()); Trace.WriteLine( "inserting data with transaction.Rollback, shouldn't invalidate the cache on SaveChanges."); try { var rnd = new Random(); var newProduct = new Product { IsActive = false, ProductName = "Product1", // It has an `IsUnique` constraint. ProductNumber = rnd.Next().ToString(), Notes = "Notes ...", UserId = 1 }; context.Products.Add(newProduct); context.SaveChanges(); // it uses a transaction behind the scene. } catch (Exception ex) { // ProductName is duplicate here and should throw an exception on save changes // and rollback the transaction automatically. Trace.WriteLine(ex.ToString()); } Trace.WriteLine("same query after insert, reading from 2nd level cache."); databaseLog.Clear(); var debugInfo3 = new EFCacheDebugInfo(); var list3 = context.Products.Include(x => x.Tags) .OrderBy(product => product.ProductNumber) .Where(product => product.IsActive == isActive && product.ProductName == name) .Cacheable(debugInfo3) .ToList(); sqlCommands = databaseLog.ToString().Trim(); Assert.AreEqual(true, string.IsNullOrWhiteSpace(sqlCommands)); Assert.AreEqual(true, debugInfo3.IsCacheHit); Assert.IsTrue(list3.Any()); } }