public void TestQueriesUsingDifferentParameterValuesWillNotUseTheCache(TestCacheProvider cacheProvider) { EFServiceProvider.RunInContext(cacheProvider, LogLevel.Debug, false, (context, loggerProvider) => { var list1 = context.Products.Include(x => x.TagProducts).ThenInclude(x => x.Tag) .OrderBy(product => product.ProductNumber) .Where(product => product.IsActive && product.ProductName == "Product1") .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .ToList(); Assert.AreEqual(0, loggerProvider.GetCacheHitCount()); var list2 = context.Products.Include(x => x.TagProducts).ThenInclude(x => x.Tag) .OrderBy(product => product.ProductNumber) .Where(product => !product.IsActive && product.ProductName == "Product1") .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .ToList(); Assert.AreEqual(0, loggerProvider.GetCacheHitCount()); var list3 = context.Products.Include(x => x.TagProducts).ThenInclude(x => x.Tag) .OrderBy(product => product.ProductNumber) .Where(product => !product.IsActive && product.ProductName == "Product2") .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .ToList(); Assert.AreEqual(0, loggerProvider.GetCacheHitCount()); var list4 = context.Products.Include(x => x.TagProducts).ThenInclude(x => x.Tag) .OrderBy(product => product.ProductNumber) .Where(product => !product.IsActive && product.ProductName == "Product2") .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .ToList(); Assert.AreEqual(1, loggerProvider.GetCacheHitCount()); }); }
public void TestEqualsMethodWillUseTheCache(TestCacheProvider cacheProvider) { EFServiceProvider.RunInContext(cacheProvider, LogLevel.Debug, false, (context, loggerProvider) => { var item1 = context.Products .Where(product => product.ProductId == 2 && product.ProductName.Equals("Product1")) .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .FirstOrDefault(); Assert.AreEqual(0, loggerProvider.GetCacheHitCount()); Assert.IsNotNull(item1); var item2 = context.Products .Where(product => product.ProductId == 2 && product.ProductName.Equals("Product1")) .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .FirstOrDefault(); Assert.AreEqual(1, loggerProvider.GetCacheHitCount()); Assert.IsNotNull(item2); var item3 = context.Products .Where(product => product.ProductId == 1 && product.ProductName.Equals("Product1")) .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .FirstOrDefault(); Assert.AreEqual(0, loggerProvider.GetCacheHitCount()); Assert.IsNull(item3); }); }
public void TestSecondLevelCacheUsingProjections(TestCacheProvider cacheProvider) { EFServiceProvider.RunInContext(cacheProvider, LogLevel.Debug, false, (context, loggerProvider) => { var isActive = true; var name = "Product1"; var list2 = context.Products .OrderBy(product => product.ProductNumber) .Where(product => product.IsActive == isActive && product.ProductName == name) .Select(x => x.ProductId) .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .ToList(); Assert.AreEqual(0, loggerProvider.GetCacheHitCount()); Assert.IsTrue(list2.Any()); list2 = context.Products .OrderBy(product => product.ProductNumber) .Where(product => product.IsActive == isActive && product.ProductName == name) .Select(x => x.ProductId) .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .ToList(); Assert.AreEqual(1, loggerProvider.GetCacheHitCount()); Assert.IsTrue(list2.Any()); }); }
public void TestSecondLevelCache_with_additional_tags_does_not_hit_the_database(TestCacheProvider cacheProvider) { EFServiceProvider.RunInContext(cacheProvider, LogLevel.Debug, false, (context, loggerProvider) => { var isActive = true; var productName = "Product2"; var list1 = context.Products .TagWith("Custom Tag") .OrderBy(product => product.ProductNumber) .Where(product => product.IsActive == isActive && product.ProductName == productName) .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .ToList(); Assert.IsTrue(list1.Any()); Assert.AreEqual(0, loggerProvider.GetCacheHitCount()); var list2 = context.Products .TagWith("Custom Tag") .OrderBy(product => product.ProductNumber) .Where(product => product.IsActive == isActive && product.ProductName == productName) .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .ToList(); Assert.IsTrue(list2.Any()); Assert.AreEqual(1, loggerProvider.GetCacheHitCount()); }); }
public void TestQueriesUsingExplicitTransactionsWillNotUseTheCache(TestCacheProvider cacheProvider) { EFServiceProvider.RunInContext(cacheProvider, LogLevel.Debug, false, (context, loggerProvider) => { using (var txn = context.Database.BeginTransaction()) { // Read and modify an entity var entity1 = context.Tags.Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)).First(); entity1.Name = "FOO"; // Save the change, cache will be invalidated context.SaveChanges(); // Read the same entity again entity1 = context.Tags.Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)).First(); // It will not get cached Assert.AreEqual(0, loggerProvider.GetCacheHitCount()); // Call some method // THIS METHOD THROWS AN EXCEPTION SO THE TRANSACTION IS NEVER COMMITTED throw new TimeoutException(); // (we never hit these lines, so the cache is not invalidated and the transaction is not committed) context.SaveChanges(); txn.Commit(); } }); }
public void TestSecondLevelCacheInTwoDifferentContextsDoesNotHitTheDatabase(TestCacheProvider cacheProvider) { var isActive = true; var name = "Product2"; EFServiceProvider.RunInContext(cacheProvider, LogLevel.Debug, false, (context, loggerProvider) => { var list2 = context.Products .OrderBy(product => product.ProductNumber) .Where(product => product.IsActive == isActive && product.ProductName == name) .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .ToList(); Assert.IsTrue(list2.Any()); Assert.AreEqual(0, loggerProvider.GetCacheHitCount()); }, (context, loggerProvider) => { var list3 = context.Products .OrderBy(product => product.ProductNumber) .Where(product => product.IsActive == isActive && product.ProductName == name) .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .ToList(); Assert.IsTrue(list3.Any()); Assert.AreEqual(1, loggerProvider.GetCacheHitCount()); }); }
public void TestTransactionRollbackShouldNotInvalidateTheCacheDependencyAutomatically(TestCacheProvider cacheProvider) { EFServiceProvider.RunInContext(cacheProvider, LogLevel.Debug, false, (context, loggerProvider) => { var isActive = true; var name = "Product1"; var list1 = context.Products.Include(x => x.TagProducts).ThenInclude(x => x.Tag) .OrderBy(product => product.ProductNumber) .Where(product => product.IsActive == isActive && product.ProductName == name) .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .ToList(); Assert.AreEqual(0, loggerProvider.GetCacheHitCount()); Assert.IsTrue(list1.Any()); var list2 = context.Products.Include(x => x.TagProducts).ThenInclude(x => x.Tag) .OrderBy(product => product.ProductNumber) .Where(product => product.IsActive == isActive && product.ProductName == name) .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .ToList(); Assert.AreEqual(1, loggerProvider.GetCacheHitCount()); Assert.IsTrue(list2.Any()); try { var newProduct = new Product { IsActive = false, ProductName = "Product1", // It has an `IsUnique` constraint. ProductNumber = RandomNumberProvider.Next().ToString(), Notes = "Notes ...", UserId = 1 }; context.Products.Add(newProduct); context.SaveChanges(); // it uses a transaction behind the scene. } catch (Exception ex) { // NOTE: This doesn't work with `EntityFrameworkInMemoryDatabase`. Because it doesn't support constraints. // ProductName is duplicate here and should throw an exception on save changes // and rollback the transaction automatically. Console.WriteLine(ex.ToString()); } var list3 = context.Products.Include(x => x.TagProducts).ThenInclude(x => x.Tag) .OrderBy(product => product.ProductNumber) .Where(product => product.IsActive == isActive && product.ProductName == name) .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .ToList(); Assert.AreEqual(1, loggerProvider.GetCacheHitCount()); Assert.IsTrue(list3.Any()); }); }
public void TestIncludeMethodAndProjectionAffectsKeyCache(TestCacheProvider cacheProvider) { var isActive = true; var name = "Product1"; EFServiceProvider.RunInContext(cacheProvider, LogLevel.Debug, false, (context, loggerProvider) => { var product1IncludeTags = context.Products .Where(product => product.IsActive == isActive && product.ProductName == name) .Include(x => x.TagProducts).ThenInclude(x => x.Tag) .Select(x => new { Name = x.ProductName, Tag = x.TagProducts.Select(y => y.Tag) }) .OrderBy(x => x.Name) .FirstOrDefault(); Assert.IsNotNull(product1IncludeTags); }, (context, loggerProvider) => { var firstProductIncludeTags = context.Products .Where(product => product.IsActive == isActive && product.ProductName == name) .Include(x => x.TagProducts).ThenInclude(x => x.Tag) .Select(x => new { Name = x.ProductName, Tag = x.TagProducts.Select(y => y.Tag) }) .OrderBy(x => x.Name) .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .FirstOrDefault(); Assert.IsNotNull(firstProductIncludeTags); Assert.AreEqual(0, loggerProvider.GetCacheHitCount()); }, (context, loggerProvider) => { var firstProductIncludeTags2 = context.Products .Where(product => product.IsActive == isActive && product.ProductName == name) .Include(x => x.TagProducts).ThenInclude(x => x.Tag) .Select(x => new { Name = x.ProductName, Tag = x.TagProducts.Select(y => y.Tag) }) .OrderBy(x => x.Name) .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .FirstOrDefault(); Assert.IsNotNull(firstProductIncludeTags2); Assert.AreEqual(1, loggerProvider.GetCacheHitCount()); }, (context, loggerProvider) => { var firstProduct = context.Products .Where(product => product.IsActive == isActive && product.ProductName == name) .Select(x => new { Name = x.ProductName, Tag = x.TagProducts.Select(y => y.Tag) }) .OrderBy(x => x.Name) .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .FirstOrDefault(); Assert.IsNotNull(firstProduct); Assert.AreEqual(1, loggerProvider.GetCacheHitCount()); }); }
public void TestSecondLevelCacheUsingDifferentSyncMethods(TestCacheProvider cacheProvider) { EFServiceProvider.RunInContext(cacheProvider, LogLevel.Debug, false, (context, loggerProvider) => { var isActive = true; var name = "Product1"; var count = context.Products .OrderBy(product => product.ProductNumber) .Where(product => product.IsActive == isActive && product.ProductName == name) .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .Count(); Assert.AreEqual(0, loggerProvider.GetCacheHitCount()); Assert.IsTrue(count > 0); var list1 = context.Products .OrderBy(product => product.ProductNumber) .Where(product => product.IsActive == isActive && product.ProductName == name) .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .ToList(); Assert.AreEqual(0, loggerProvider.GetCacheHitCount()); Assert.IsTrue(list1.Any()); var product1 = context.Products .OrderBy(product => product.ProductNumber) .Where(product => product.IsActive == isActive && product.ProductName == name) .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .FirstOrDefault(); Assert.AreEqual(0, loggerProvider.GetCacheHitCount()); Assert.IsTrue(product1 != null); var any = context.Products .OrderBy(product => product.ProductNumber) .Where(product => product.IsActive == isActive && product.ProductName == "Product2") .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .Any(); Assert.AreEqual(0, loggerProvider.GetCacheHitCount()); Assert.IsTrue(any); var sum = context.Products .OrderBy(product => product.ProductNumber) .Where(product => product.IsActive == isActive && product.ProductName == "Product2") .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .Sum(x => x.ProductId); Assert.AreEqual(0, loggerProvider.GetCacheHitCount()); Assert.IsTrue(sum > 0); }); }
public void TestIncludeMethodAffectsKeyCache(TestCacheProvider cacheProvider) { EFServiceProvider.RunInContext(cacheProvider, LogLevel.Debug, false, (context, loggerProvider) => { var firstProductIncludeTags = context.Products.Include(x => x.TagProducts).ThenInclude(x => x.Tag) .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .FirstOrDefault(); Assert.IsNotNull(firstProductIncludeTags); Assert.AreEqual(0, loggerProvider.GetCacheHitCount()); var firstProduct = context.Products.Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)).FirstOrDefault(); Assert.IsNotNull(firstProduct); Assert.AreEqual(0, loggerProvider.GetCacheHitCount()); }); }
public void TestIncludeMethodAndProjectionAffectsKeyCache(bool useRedis) { EFServiceProvider.RunInContext(useRedis, LogLevel.Information, false, (context, loggerProvider) => { var product1IncludeTags = context.Products .Include(x => x.TagProducts).ThenInclude(x => x.Tag) .Select(x => new { Name = x.ProductName, Tag = x.TagProducts.Select(y => y.Tag) }) .OrderBy(x => x.Name) .FirstOrDefault(); Assert.IsNotNull(product1IncludeTags); }, (context, loggerProvider) => { var firstProductIncludeTags = context.Products .Include(x => x.TagProducts).ThenInclude(x => x.Tag) .Select(x => new { Name = x.ProductName, Tag = x.TagProducts.Select(y => y.Tag) }) .OrderBy(x => x.Name) .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .FirstOrDefault(); Assert.IsNotNull(firstProductIncludeTags); Assert.AreEqual(0, loggerProvider.GetCacheHitCount()); }, (context, loggerProvider) => { var firstProductIncludeTags2 = context.Products .Include(x => x.TagProducts).ThenInclude(x => x.Tag) .Select(x => new { Name = x.ProductName, Tag = x.TagProducts.Select(y => y.Tag) }) .OrderBy(x => x.Name) .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .FirstOrDefault(); Assert.IsNotNull(firstProductIncludeTags2); Assert.AreEqual(1, loggerProvider.GetCacheHitCount()); }, (context, loggerProvider) => { var firstProduct = context.Products .Select(x => new { Name = x.ProductName, Tag = x.TagProducts.Select(y => y.Tag) }) .OrderBy(x => x.Name) .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .FirstOrDefault(); Assert.IsNotNull(firstProduct); Assert.AreEqual(1, loggerProvider.GetCacheHitCount()); }); }
public void TestUsersWithAllDataTypes(TestCacheProvider cacheProvider) { EFServiceProvider.RunInContext(cacheProvider, LogLevel.Debug, false, (context, loggerProvider) => { var items1 = context.Users .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .ToList(); Assert.AreEqual(0, loggerProvider.GetCacheHitCount()); Assert.IsNotNull(items1); var items2 = context.Users .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .ToList(); Assert.AreEqual(1, loggerProvider.GetCacheHitCount()); Assert.IsNotNull(items2); }); }
public void TestInsertingDataIntoTheSameTableShouldInvalidateTheCacheAutomatically(TestCacheProvider cacheProvider) { EFServiceProvider.RunInContext(cacheProvider, LogLevel.Debug, false, (context, loggerProvider) => { var isActive = true; var name = "Product2"; var list1 = context.Products.Include(x => x.TagProducts).ThenInclude(x => x.Tag) .OrderBy(product => product.ProductNumber) .Where(product => product.IsActive == isActive && product.ProductName == name) .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .ToList(); Assert.AreEqual(0, loggerProvider.GetCacheHitCount()); Assert.IsTrue(list1.Any()); var list2 = context.Products.Include(x => x.TagProducts).ThenInclude(x => x.Tag) .OrderBy(product => product.ProductNumber) .Where(product => product.IsActive == isActive && product.ProductName == name) .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .ToList(); Assert.AreEqual(1, loggerProvider.GetCacheHitCount()); Assert.IsTrue(list2.Any()); var newProduct = new Product { IsActive = false, ProductName = $"Product{RandomNumberProvider.Next()}", ProductNumber = RandomNumberProvider.Next().ToString(), Notes = "Notes ...", UserId = 1 }; context.Products.Add(newProduct); context.SaveChanges(); var list3 = context.Products.Include(x => x.TagProducts).ThenInclude(x => x.Tag) .OrderBy(product => product.ProductNumber) .Where(product => product.IsActive == isActive && product.ProductName == name) .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .ToList(); Assert.AreEqual(0, loggerProvider.GetCacheHitCount()); Assert.IsTrue(list3.Any()); }); }
public void TestRemoveTptDataShouldInvalidateTheCacheAutomatically(TestCacheProvider cacheProvider) { EFServiceProvider.RunInContext(cacheProvider, LogLevel.Debug, false, (context, loggerProvider) => { var list1 = context.Posts.OfType <Page>().Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)).ToList(); Assert.AreEqual(0, loggerProvider.GetCacheHitCount()); var list2 = context.Posts.OfType <Page>().Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)).ToList(); Assert.AreEqual(1, loggerProvider.GetCacheHitCount()); var post1 = context.Posts.First(post => post.Id == 1); post1.Title = $"Post{RandomNumberProvider.Next()}"; context.SaveChanges(); var list3 = context.Posts.OfType <Page>().Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)).ToList(); Assert.AreEqual(0, loggerProvider.GetCacheHitCount()); }); }
public void TestNullValuesWillUseTheCache(TestCacheProvider cacheProvider) { EFServiceProvider.RunInContext(cacheProvider, LogLevel.Debug, false, (context, loggerProvider) => { var item1 = context.Products .OrderBy(product => product.ProductNumber) .Where(product => product.IsActive && product.ProductName == "Product1xx") .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .FirstOrDefault(); Assert.AreEqual(0, loggerProvider.GetCacheHitCount()); Assert.IsNull(item1); var item2 = context.Products .OrderBy(product => product.ProductNumber) .Where(product => product.IsActive && product.ProductName == "Product1xx") .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .FirstOrDefault(); Assert.AreEqual(1, loggerProvider.GetCacheHitCount()); Assert.IsNull(item2); }); }
public void TestInsertingDataToRelatedTablesShouldInvalidateTheCacheDependencyAutomatically(TestCacheProvider cacheProvider) { EFServiceProvider.RunInContext(cacheProvider, LogLevel.Debug, false, (context, loggerProvider) => { var isActive = true; var name = "Product1"; var list1 = context.Products.Include(x => x.TagProducts).ThenInclude(x => x.Tag) .OrderBy(product => product.ProductNumber) .Where(product => product.IsActive == isActive && product.ProductName == name) .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .ToList(); Assert.AreEqual(0, loggerProvider.GetCacheHitCount()); Assert.IsTrue(list1.Any()); var list2 = context.Products.Include(x => x.TagProducts).ThenInclude(x => x.Tag) .OrderBy(product => product.ProductNumber) .Where(product => product.IsActive == isActive && product.ProductName == name) .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .ToList(); Assert.AreEqual(1, loggerProvider.GetCacheHitCount()); Assert.IsTrue(list2.Any()); var tag = new Tag { Name = $"Tag {RandomNumberProvider.Next()}" }; context.Tags.Add(tag); context.SaveChanges(); var list3 = context.Products.Include(x => x.TagProducts).ThenInclude(x => x.Tag) .OrderBy(product => product.ProductNumber) .Where(product => product.IsActive == isActive && product.ProductName == name) .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .ToList(); Assert.AreEqual(0, loggerProvider.GetCacheHitCount()); Assert.IsTrue(list3.Any()); }); }
public void TestInsertingDataToOtherTablesShouldNotInvalidateTheCacheDependencyAutomatically(bool useRedis) { EFServiceProvider.RunInContext(useRedis, LogLevel.Information, false, (context, loggerProvider) => { var isActive = true; var name = "Product4"; var list1 = context.Products.Include(x => x.TagProducts).ThenInclude(x => x.Tag) .OrderBy(product => product.ProductNumber) .Where(product => product.IsActive == isActive && product.ProductName == name) .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .ToList(); Assert.AreEqual(0, loggerProvider.GetCacheHitCount()); Assert.IsTrue(!list1.Any()); var list2 = context.Products.Include(x => x.TagProducts).ThenInclude(x => x.Tag) .OrderBy(product => product.ProductNumber) .Where(product => product.IsActive == isActive && product.ProductName == name) .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .ToList(); Assert.AreEqual(1, loggerProvider.GetCacheHitCount()); Assert.IsTrue(!list2.Any()); var user = new User { Name = $"User {RandomNumberProvider.Next()}" }; context.Users.Add(user); context.SaveChanges(); var list3 = context.Products.Include(x => x.TagProducts).ThenInclude(x => x.Tag) .OrderBy(product => product.ProductNumber) .Where(product => product.IsActive == isActive && product.ProductName == name) .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .ToList(); Assert.AreEqual(1, loggerProvider.GetCacheHitCount()); Assert.IsTrue(!list3.Any()); }); }
public void TestCachingByteArrays(TestCacheProvider cacheProvider) { EFServiceProvider.RunInContext(cacheProvider, LogLevel.Debug, false, (context, loggerProvider) => { User user1; const string user1Name = "User1"; var binaryData = new byte[] { 1, 2, 3 }; if (!context.Users.Any(user => user.Name == user1Name)) { user1 = new User { Name = user1Name, ImageData = binaryData }; user1 = context.Users.Add(user1).Entity; } else { user1 = context.Users.First(user => user.Name == user1Name); user1.ImageData = binaryData; } context.SaveChanges(); var userData = context.Users .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .FirstOrDefault(p => p.Id == user1.Id); Assert.AreEqual(0, loggerProvider.GetCacheHitCount()); Assert.IsNotNull(userData); CollectionAssert.AreEqual(binaryData, userData.ImageData); userData = context.Users .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .FirstOrDefault(p => p.Id == user1.Id); Assert.AreEqual(1, loggerProvider.GetCacheHitCount()); Assert.IsNotNull(userData); CollectionAssert.AreEqual(binaryData, userData.ImageData); }); }
public void PerformanceTest(bool useRedis) { const decimal loopCount = 1000; EFServiceProvider.RunInContext(useRedis, LogLevel.Warning, false, (context, debugLoggerProvider) => { Stopwatch watch = new Stopwatch(); watch.Start(); // run normal queries for (int i = 0; i < loopCount; i++) { var result = context.Posts.Where(post => post.Id >= 0).Take(100).ToList(); } var uncachedTimeSpan = watch.Elapsed; // cache the query result var posts = context.Posts.Where(post => post.Id >= 0).Take(100).Cacheable().ToList(); watch.Restart(); // run cached queries for (int i = 0; i < loopCount; i++) { var result = context.Posts.Where(post => post.Id >= 0).Take(100).Cacheable().ToList(); } var cachedTimeSpan = watch.Elapsed; var message = $"Average database query duration [+{TimeSpan.FromTicks((long)(uncachedTimeSpan.Ticks / loopCount))}].\n" + $"Average cache query duration [+{TimeSpan.FromTicks((long)(cachedTimeSpan.Ticks / loopCount))}].\n" + $"Cached queries are x{(uncachedTimeSpan.Ticks / (decimal)cachedTimeSpan.Ticks) - 1:N2} times faster."; Assert.IsTrue(uncachedTimeSpan > cachedTimeSpan, message); }); }
public void TestQueriesUsingExplicitTransactionsWillInvalidateTheCache(TestCacheProvider cacheProvider) { var rnd = new Random(); EFServiceProvider.RunInContext(cacheProvider, LogLevel.Debug, false, (context, loggerProvider) => { // Read and cache data var entity0 = context.Tags.Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)).First(); using (var txn = context.Database.BeginTransaction()) { // Read and modify an entity. var entity1 = context.Tags.Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)).First(); // Reading the data from the database, not cache. Assert.AreEqual(0, loggerProvider.GetCacheHitCount()); entity1.Name = $"FOO{rnd.Next()}"; // Save the change, cache will be invalidated. context.SaveChanges(); // Read the same entity again. entity1 = context.Tags.Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)).First(); // Reading the data from the database, not cache. Assert.AreEqual(0, loggerProvider.GetCacheHitCount()); context.SaveChanges(); txn.Commit(); } // `After` committing the transaction, the related query cache should be invalidated. var entity2 = context.Tags.Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)).First(); // Reading the data from the database after invalidation, not cache. Assert.AreEqual(0, loggerProvider.GetCacheHitCount()); }); }
public void TestRemoveDataShouldInvalidateTheCacheAutomatically(TestCacheProvider cacheProvider) { EFServiceProvider.RunInContext(cacheProvider, LogLevel.Debug, false, (context, loggerProvider) => { var isActive = false; var name = "Product4"; var list1 = context.Products.Include(x => x.TagProducts).ThenInclude(x => x.Tag) .OrderBy(product => product.ProductNumber) .Where(product => product.IsActive == isActive && product.ProductName == name) .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .ToList(); Assert.AreEqual(0, loggerProvider.GetCacheHitCount()); Assert.IsNotNull(list1); var list2 = context.Products.Include(x => x.TagProducts).ThenInclude(x => x.Tag) .OrderBy(product => product.ProductNumber) .Where(product => product.IsActive == isActive && product.ProductName == name) .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .ToList(); Assert.AreEqual(1, loggerProvider.GetCacheHitCount()); Assert.IsTrue(list2.Any()); var product1 = context.Products.First(product => product.ProductName == name); product1.Notes = $"Test ... {RandomNumberProvider.Next()}"; context.SaveChanges(); var list3 = context.Products.Include(x => x.TagProducts).ThenInclude(x => x.Tag) .OrderBy(product => product.ProductNumber) .Where(product => product.IsActive == isActive && product.ProductName == name) .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .ToList(); Assert.AreEqual(0, loggerProvider.GetCacheHitCount()); Assert.IsNotNull(list3); }); }
public void Test2DifferentCollectionsWillNotUseTheCache(TestCacheProvider cacheProvider) { EFServiceProvider.RunInContext(cacheProvider, LogLevel.Debug, false, (context, loggerProvider) => { var collection1 = new[] { 1, 2, 3 }; var item1 = context.Products .Where(product => collection1.Contains(product.ProductId)) .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .FirstOrDefault(); Assert.AreEqual(0, loggerProvider.GetCacheHitCount()); Assert.IsNotNull(item1); var collection2 = new[] { 1, 2, 3, 4 }; var item2 = context.Products .Where(product => collection2.Contains(product.ProductId)) .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .FirstOrDefault(); Assert.AreEqual(0, loggerProvider.GetCacheHitCount()); Assert.IsNotNull(item2); }); }
public void TestSecondLevelCacheUsingTwoCountMethods(TestCacheProvider cacheProvider) { EFServiceProvider.RunInContext(cacheProvider, LogLevel.Debug, false, (context, loggerProvider) => { var isActive = true; var name = "Product3"; var count = context.Products .OrderBy(product => product.ProductNumber) .Where(product => product.IsActive == isActive && product.ProductName == name) .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .Count(); Assert.AreEqual(0, loggerProvider.GetCacheHitCount(), $"cacheProvider: {cacheProvider}"); Assert.IsTrue(count > 0); count = context.Products .OrderBy(product => product.ProductNumber) .Where(product => product.IsActive == isActive && product.ProductName == name) .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .Count(); Assert.AreEqual(1, loggerProvider.GetCacheHitCount()); Assert.IsTrue(count > 0); }); }
public void TestAddThenRemoveDataShouldInvalidateTheCacheAutomatically(TestCacheProvider cacheProvider) { EFServiceProvider.RunInContext(cacheProvider, LogLevel.Debug, false, (context, loggerProvider) => { User user1; const string user1Name = "User1"; if (!context.Users.Any(user => user.Name == user1Name)) { user1 = new User { Name = user1Name, AddDate = new DateTime(2020, 4, 3, 17, 50, 39, 503), UpdateDate = null, Points = 1000, IsActive = true, ByteValue = 1, CharValue = 'C', DateTimeOffsetValue = new DateTimeOffset(new DateTime(2020, 4, 3, 17, 50, 39, 503)), DecimalValue = 1.1M, DoubleValue = 1.3, FloatValue = 1.2f, GuidValue = new Guid("236bbe40-b861-433c-8789-b152a99cfe3e"), TimeSpanValue = new TimeSpan(1, 0, 0, 0, 0), ShortValue = 2, ByteArrayValue = new byte[] { 1, 2 }, UintValue = 1, UlongValue = 1, UshortValue = 1 }; user1 = context.Users.Add(user1).Entity; } else { user1 = context.Users.First(user => user.Name == user1Name); } var userOne = context.Users.Cacheable().First(user => user.Name == user1Name); userOne = context.Users.Cacheable().First(user => user.Name == user1Name); Assert.IsNotNull(userOne); loggerProvider.ClearItems(); var product = new Product { IsActive = false, ProductName = $"Product{RandomNumberProvider.Next()}", ProductNumber = RandomNumberProvider.Next().ToString(), Notes = "Notes ...", UserId = 1 }; context.Products.Add(product); context.SaveChanges(); var p98 = context.Products .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .FirstOrDefault(p => p.ProductId == product.ProductId); Assert.AreEqual(0, loggerProvider.GetCacheHitCount()); Assert.IsNotNull(p98); var firstQueryWithWhereClauseResult = context.Products.Where(p => p.ProductId == product.ProductId) .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .FirstOrDefault(); Assert.AreEqual(1, loggerProvider.GetCacheHitCount()); Assert.IsNotNull(firstQueryWithWhereClauseResult); context.Products.Remove(product); context.SaveChanges(); p98 = context.Products .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .FirstOrDefault(p => p.ProductId == product.ProductId); Assert.AreEqual(0, loggerProvider.GetCacheHitCount()); Assert.IsNull(p98); var firstQueryWithWhereClauseResult2 = context.Products.Where(p => p.ProductId == product.ProductId) .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .FirstOrDefault(); Assert.AreEqual(1, loggerProvider.GetCacheHitCount()); Assert.IsNull(firstQueryWithWhereClauseResult2); p98 = context.Products.FirstOrDefault(p => p.ProductId == product.ProductId); Assert.IsNull(p98); }); }
public void TestAddThenRemoveDataShouldInvalidateTheCacheAutomatically(bool useRedis) { EFServiceProvider.RunInContext(useRedis, LogLevel.Information, false, (context, loggerProvider) => { User user1; const string user1Name = "User1"; if (!context.Users.Any(user => user.Name == user1Name)) { user1 = new User { Name = user1Name }; user1 = context.Users.Add(user1).Entity; } else { user1 = context.Users.First(user => user.Name == user1Name); } var product = new Product { IsActive = false, ProductName = $"Product{RandomNumberProvider.Next()}", ProductNumber = RandomNumberProvider.Next().ToString(), Notes = "Notes ...", UserId = 1 }; context.Products.Add(product); context.SaveChanges(); var p98 = context.Products .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .FirstOrDefault(p => p.ProductId == product.ProductId); Assert.AreEqual(0, loggerProvider.GetCacheHitCount()); Assert.IsNotNull(p98); var firstQueryWithWhereClauseResult = context.Products.Where(p => p.ProductId == product.ProductId) .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .FirstOrDefault(); Assert.AreEqual(1, loggerProvider.GetCacheHitCount()); Assert.IsNotNull(firstQueryWithWhereClauseResult); context.Products.Remove(product); context.SaveChanges(); p98 = context.Products .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .FirstOrDefault(p => p.ProductId == product.ProductId); Assert.AreEqual(0, loggerProvider.GetCacheHitCount()); Assert.IsNull(p98); var firstQueryWithWhereClauseResult2 = context.Products.Where(p => p.ProductId == product.ProductId) .Cacheable(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(45)) .FirstOrDefault(); Assert.AreEqual(1, loggerProvider.GetCacheHitCount()); Assert.IsNull(firstQueryWithWhereClauseResult2); p98 = context.Products.FirstOrDefault(p => p.ProductId == product.ProductId); Assert.IsNull(p98); }); }