C# 如果使用EF查询,.Net核心IMemoryCache将继续调用数据库
我正在使用IMemoryCache在缓存中存储数据。。。但它会不断向sql Server发送sql调用,即使在缓存存在的情况下执行不会运行该代码 我的查找服务C# 如果使用EF查询,.Net核心IMemoryCache将继续调用数据库,c#,asp.net-core,C#,Asp.net Core,我正在使用IMemoryCache在缓存中存储数据。。。但它会不断向sql Server发送sql调用,即使在缓存存在的情况下执行不会运行该代码 我的查找服务 public class QueryLookups { private IMemoryCache _memoryCache; public QueryLookups(DbContexts.AppsecDbContext ctx, IMemoryCache memoryCache)
public class QueryLookups
{
private IMemoryCache _memoryCache;
public QueryLookups(DbContexts.AppsecDbContext ctx, IMemoryCache memoryCache)
{
context = ctx;
_memoryCache = memoryCache;
}
public DbContexts.AppsecDbContext context
{
get; set;
}
public IEnumerable<string> GetCourseAreas()
{
IEnumerable<string> result;
// TryGet returns true if the cache entry was found
if (!_memoryCache.TryGetValue("CourseAreas", out result))
{
oak.Frameworks.Utils.Debug("No Cache found for 'CourseAreas' - Get from Database");
result = context.CourseAreas.Where(s => string.IsNullOrWhiteSpace(s.Area) == false).Select(s => s.Area).Distinct().OrderBy(s => s);
_memoryCache.Set("CourseAreas", result, DateTime.Now.AddHours(1)); // 1 hour cache
}
return result;
}
public IEnumerable<string> GetAcademicYearIDs()
{
IEnumerable<string> result;
// TryGet returns true if the cache entry was found
if (!_memoryCache.TryGetValue("AcademicYearIDs", out result))
{
oak.Frameworks.Utils.Debug("No Cache found for 'AcademicYearIDs' - Get from Database");
IDbConnection db = context.Database.GetDbConnection();
result = db.Query<string>("SELECT DISTINCT AcademicYearID FROM dbo.ER_vBaseStudents;");
_memoryCache.Set("AcademicYearIDs", result, DateTime.Now.AddHours(5)); // 5 hours cache
}
return result;
}
}
测试控制器
public IActionResult Test()
{
return View();
}
理论上,它不应该向SQL Server发送db命令。但是根据SQL分析器,它仍然在发送数据,即使它没有运行代码从那里获取数据。它命中缓存并从缓存返回数据。但它仍然在数据库中运行selectxxxx
奇怪的是,在我的查找服务中,有两种方法。使用Dapper的getAcademyYearIds()方法没有执行相同的操作。它只在我使用EF语法的GetCourseAreas中使用
你能帮我解决这个问题吗?这些数据库调用非常快,不到100毫秒。但我想知道为什么它一直在做,我做错了什么
回答
这要归功于我在伦敦.Net用户群遇到的大师。如果你回答这个问题,我会把你的答案记为正确答案
原因是EFCore的延迟加载特性。我直接缓存实体,而不从数据库读取数据。相反,我添加了.ToList()
,以强制读取并将结果放回缓存。而且它工作得很好
result = context.CourseAreas.Where(s => string.IsNullOrWhiteSpace(s.Area) == false).Select(s => s.Area).Distinct().OrderBy(s => s).ToList();
_memoryCache.Set("CourseAreas", result, DateTime.Now.AddHours(1)); // 1 hour cache
我想这是为了阻止缓存过时。您应该能够更改刷新的时间速率,尽管您使用的EF版本是什么?Entity Framework Core“Microsoft.EntityFrameworkCore.Tools”:“1.1.0-preview4-final”
public IActionResult Test()
{
return View();
}
result = context.CourseAreas.Where(s => string.IsNullOrWhiteSpace(s.Area) == false).Select(s => s.Area).Distinct().OrderBy(s => s).ToList();
_memoryCache.Set("CourseAreas", result, DateTime.Now.AddHours(1)); // 1 hour cache