gpt4 book ai didi

c# - 如果使用 EF 查询,.Net Core IMemoryCache 会继续调用数据库

转载 作者:行者123 更新时间:2023-11-30 18:18:12 26 4
gpt4 key购买 nike

我正在使用 IMemoryCache 将数据存储在缓存中...但它会不断向 SQL Server 发送 sql 调用,即使在缓存存在的情况下执行不会运行该代码。

我的查找服务

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;
}

}

我的测试View.cshtml

<div class="form-inline">
<select class="form-control" asp-items="@LookupService.GetAcademicYearIDs().Select(g => new SelectListItem() { Text = g, Value = g })">
<option value="">- All Years -</option>
</select>
<select class="form-control" asp-items="@LookupService.GetCourseAreas().Select(g => new SelectListItem() { Text = g, Value = g })">
<option value="">- All Areas -</option>
</select>
</div>

_ViewImports.cshtml

@using MyProject
@inject MyProject.Queries.QueryLookups LookupService
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

测试 Controller

public IActionResult Test()
{
return View();
}

理论上,它不应该向 SQL Server 发送 db 命令。但是根据 SQL 事件探查器,它仍在发送,即使它没有运行从那里获取数据的代码。它命中缓存并从缓存返回数据。但它仍然对数据库运行 SELECT xxxx。

奇怪的是,在我的查找服务中,有两种方法。使用 Dapper 的 GetAcademicYearIDs() 方法并没有做同样的事情。它仅针对我使用 EF 语法的 GetCourseAreas 执行此操作。

你能帮我解决这个问题吗?这些数据库调用非常快,不到 100 毫秒。但我想知道为什么它一直这样做以及我做错了什么。

enter image description here

回答感谢我在 London.Net 用户组遇到的专家。如果您回答了问题,我会将您的答案标记为正确答案。

原因是因为 EFCore 的 Lazy Loading 特性。我直接缓存实体而不从数据库读取数据。取而代之的是,我添加了 .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

最佳答案

我认为调用是为了阻止缓存过时。您应该能够通过 Microsoft IMemeoryCache 更改刷新的时间速率

关于c# - 如果使用 EF 查询,.Net Core IMemoryCache 会继续调用数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41980643/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com