VahidN / EFSecondLevelCache.Core

Entity Framework Core Second Level Caching Library
Apache License 2.0
326 stars 51 forks source link

Queries are not cached if a variable is used in the query. #41

Closed Sabbi closed 5 years ago

Sabbi commented 5 years ago

Summary of the issue

Queries are not cached (IsCacheHit is always false) if a variable is used in the query.

Environment

The in-use version: 2.4.0
Operating system:  Windows 10 / .NET Core 2.2
IDE: (e.g. Visual Studio 2015) Visual Studio 2019
Database: MySQL with Pomelo.EntityFrameworkCore.Mysql (2.2.0)

Example code/Steps to reproduce:

Working code:

var result = _dbContext.Tests.Where(p => p.TestId == 1).Cacheable(dinfo).FirstOrDefault();

as expected, on the first call IsCacheHit is false, on subsequent calls it's true

Non-Working code:

var t = 1;
var result = _dbContext.Tests.Where(p => p.TestId == t).Cacheable(dinfo).FirstOrDefault();

on all calls, IsCacheHit is false. Also EFCacheKey.KeyHash changes on every call, as does the Key inside EFCacheKey.Key

Output:

Non-Working output of EFCacheDebugInfo (KeyHash changes with every call):

IsCacheHit: False

EFCacheKey.KeyHash: 13A01C94

EFCacheKey.Key:
SELECT `p`.`TestId`, `p`.`Content`
FROM `Tests` AS `p`
WHERE `p`.`TestId` = 1
LIMIT 1;6EED9AE3;.Call System.Linq.Queryable.FirstOrDefault(.Call Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.AsNoTracking(.Call System.Linq.Queryable.Where(
            .Constant(Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1[corecache.Data.Test]),
            '(.Lambda #Lambda1))))

.Lambda #Lambda1(corecache.Data.Test $p) {
    $p.TestId == .Constantc__DisplayClass6_0>(corecache.Controllers.HomeController+<>c__DisplayClass6_0).t
};

Working output of EFCacheDebugInfo

IsCacheHit: True

EFCacheKey.KeyHash: 41B68F6F

EFCacheKey.Key:
SELECT `p`.`TestId`, `p`.`Content`
FROM `Tests` AS `p`
WHERE `p`.`TestId` = 1
LIMIT 1;3213A02B;.Call System.Linq.Queryable.FirstOrDefault(.Call Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.AsNoTracking(.Call System.Linq.Queryable.Where(
            .Constant(Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1[corecache.Data.Test]),
            '(.Lambda #Lambda1))))

.Lambda #Lambda1(corecache.Data.Test $p) {
    $p.TestId == 1
};

Same problem occurs with FirstOrDefault:

 var result = _dbContext.Tests.Cacheable(dinfo).FirstOrDefault(p => p.TestId == t);
VahidN commented 5 years ago

Thanks for reporting it. It's fixed via #https://github.com/VahidN/EFSecondLevelCache.Core/commit/f37a6b63bbe95c61ba3cb2134bfdc2657d7e0582

Sabbi commented 5 years ago

Wow, that was fast! Thank you so much!

lock[bot] commented 4 years ago

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related problems.