c# - 使用带有大量 Include() 的 EF Core 时如何正确缓存查询结果?
问题描述
我正在使用https://github.com/VahidN/EFCoreSecondLevelCacheInterceptor包在我的 ASP.NET Core 应用程序中缓存 EF Core 查询结果。根据创作者的说法,它是这样工作的:
EF 命令的结果将存储在缓存中,因此相同的 EF 命令将从缓存中检索其数据,而不是再次针对数据库执行它们。
因此,如果生成的 SQL 相同,此库将返回缓存结果。
问题是我在查询数据库时使用了很多 Include() 方法。这是必需的,因为某些页面显示了存储在不同相关数据库表中的大量信息。此外,查询包含当前用户特定的信息,例如当前用户是否喜欢该帖子。正如我所听到的那样缓存用户特定的信息是不正确的,并且会导致冗余缓存条目,因为唯一正在更改的数据是当前用户 ID。
查询示例:
var post = dbContext.Posts
.Where(p => p.Id == 1)
.Include(p => p.Comments)
.Include(p => p.VoteTracker
.Where(t => t.UserId == "{current user ID}"))
// ... other Include(...) calls
.ToList();
生成的 SQL 可能非常庞大,有很多 JOIN。所以这里缓存的问题是:
- 如果评论被更改,那么上面的整个查询也将失效,因为这个库
使用其拦截器监视所有 CRUD 操作,然后自动使相关的缓存条目无效
- 在查询中包含当前用户特定信息会创建许多相同的缓存条目,这些条目仅因当前用户特定信息而异
在这里缓存的更好方法是什么?
首先想到的是拥有可以缓存的单独查询。例如:
// Post and Comments query will be cached
var post = dbContext.Posts.SingleOrDefault(p => p.Id == 1);
var comments = dbContext.Comments
.Where(c => c.PostId == 1)
.ToList();
// This one will be excluded from caching (because of user-specific info)
var voteTracker = dbContext.VoteTrackers
.SingleOrDefault(t => t.PostId == 1 && t.UserId == "{current user ID}");
这是一个好方法吗?如果不是哪个更好?
我为此苦苦挣扎,但很难找到正确的解决方案。非常感谢您!:)
解决方案
推荐阅读
- python - 检查某个日期是否存在多对多关系,然后排除该条目
- javascript - 节点 js if/else 使用 puppeteer 无法正常运行
- c - 调用时未创建 crontab 文件
- akka - 我们可以在基于参与者的系统中拥有全局状态吗?
- azure - 如何忽略 Azure API Manager validate-jwt 策略中的特定 URL
- google-apps-script - 在宏中使用单元格的内容,如值
- django - 如何创建 django 多种用户类型
- qt - QML自定义按钮不能发出按下信号,因为它不是一个函数?
- powershell - 如何在 Azure DevOps 中使用 SharePointPnpPowerShellOnline PowerShell 模块?
- javascript - Node.js中的Websocket Server从手机APP访问时返回RSV1错误