[英]Why is DBContext is disposed after putting it in IMemoryCache (.NET Core / EF Core)
[英].Net Core IMemoryCache keep calling Database if EF Query is used
我正在使用IMemoryCache在Cache中存儲數據...但是它仍然向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
的TestController
public IActionResult Test()
{
return View();
}
理論上,它不應該將db命令發送到SQL Server。 但是根據SQL事件探查器的說法,它仍在發送,即使它沒有運行代碼來從那里獲取數據。 它命中緩存並從緩存中返回數據。 但它仍然運行SELECT xxxx到數據庫。
奇怪的是,在我的查找服務中,有兩種方法。 使用Dapper的GetAcademicYearIDs()方法沒有做同樣的事情。 它只用於我使用EF語法的GetCourseAreas。
你能幫我解決這個問題嗎? 這些數據庫調用速度非常快,不到100毫秒。 但我想知道為什么它一直在做,我做錯了什么。
回答信用證歸於我在London.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
我認為這個調用是為了阻止緩存過時。 您應該能夠通過Microsoft IMemeoryCache更改它刷新的時間速率
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.