簡體   English   中英

.Net Core IMemoryCache在使用EF Query時繼續調用Database

[英].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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM