加快应用程序速度的一种方法是在数据库旁边添加缓存层。 通常我们会编写辅助方法来从数据库中读取数据,将其序列化并将其存储在缓存中。 NCache 与 Entity Framework Core 集成,只需几行代码即可缓存我们的实体。 让我们介绍一下如何实现缓存侧策略 NCache 和实体框架核心。
Entity Framework Core 没有内置的缓存机制。 我们必须自己推出。 但, NCache 有一组方便的扩展方法来轻松缓存我们的查询结果。
通过这种集成,我们利用了所有可扩展性和复制功能 NCache 在我们的实体框架应用程序中。
让我们创建一个示例 ASP.NET Core 6.0 应用程序缓存 Entity Framework Core 查询以显示目录中评分最高的 10 部电影。
如何注册 NCache 与实体框架核心
在开始之前,我们先确保 NCache 安装。 我们需要企业版或专业版。
创建 ASP 后.NET Core Web API 应用程序,让我们安装 EntityFrameworkCore。NCache NuGet 包。 如果我们使用专业版,我们将安装 EntityFrameworkCore。NCache.专业的NuGet包代替。
注册 NCache 使用实体框架,在我们应用程序的 Program.cs 文件中,我们编写,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
using Alachisoft.NCache.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; var builder = WebApplication.CreateBuilder(args); builder.Services.AddDbContext(options => { var config = builder.Configuration; var connectionString = config.GetConnectionString("Default"); // Configure NCache with Entity Framework // We need a cacheId and database type NCacheConfiguration.Configure(cacheId: "demoCache", DependencyType.SqlServer); NCacheConfiguration.ConfigureLogger(); options.UseSqlServer(connectionString); }); builder.Services.AddControllers(); var app = builder.Build(); app.MapControllers(); app.Run(); |
这看起来就像一个普通的 ASP.NET Core 使用 Entity Framework Core 的应用程序,除了两个方法:Configure() 和 ConfigureLogger() NCache组态。
使用Configure()方法,我们指定cacheId和数据库类型。 我们使用 demoCache(默认缓存实例)和 DependencyType.SqlServer。 当然,我们应该从配置文件中读取cacheId。
在这个例子中,我们只使用了cacheId和数据库类型,但我们也可以传递 额外的配置选项 比如重试和超时。
ConfigureLogger() 设置 ASP 的底层日志记录抽象.NET Core.
如何插入和缓存 Entity Framework Core 结果 NCache
注册后 NCache 进入 Entity Framework Core,我们正在阅读开始缓存我们的电影。
缓存 Entity Framework Core 结果
让我们创建一个 MoviesController 类来读取 10 部最好的电影并将它们缓存在 NCache. 像这样,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
using Alachisoft.NCache.EntityFrameworkCore; using Microsoft.AspNetCore.Mvc; namespace Movies.Controllers; [ApiController] [Route("[controller]")] public class MoviesController : ControllerBase { private readonly DatabaseContext _database; public MoviesController(DatabaseContext database) { _database = database; } [HttpGet] public async Task<IEnumerable> Get() { return await _database .Movies .OrderByDescending(m => m.Rating) .ThenBy(m => m.ReleaseYear) .Take(10) .FromCacheAsync(new CachingOptions { StoreAs = StoreAs.Collection }); } } |
NCache 在现有 Entity Framework Core 方法之上引入了新的扩展方法。
在使用 LINQ 查询检索按评级和发行年份排序的 10 部电影之后,我们添加了一个新方法:FromCacheAsync()。
FromCacheAsync()
缓存 LINQ 查询的结果并返回它。 如果我们的缓存没有这个结果,它就会去数据库然后缓存它。 如果我们无法连接到我们的缓存服务器, NCache 将从我们的数据库返回结果。 然后它将继续重试用我们的结果填充缓存。
当使用 FromCacheAsync() 时,我们传递一个 CachingOptions 参数,告诉 NCache 将查询结果作为一个整体而不是单独的条目进行缓存。 有 更多的选择 指定过期时间和优先级。
FromCacheAsyn() 有一个同步替代方案 FromCache()
。 与异步版本不同,FromCache() 返回新项目的缓存键作为输出参数。
LoadIntoCache 和 FromCacheOnly
除了 FromCache() 和 FromCacheAsync() 之外, NCache 还有另外两个方法:LoadIntoCache() 和 FromCacheOnly()。
LoadIntoCache() 会在每次调用时覆盖缓存的结果。 它的工作方式类似于 FromCache(),每次调用都会发生缓存未命中。 此方法最适合频繁更改的数据以及我们始终需要数据的最新副本的场景。
FromCacheOnly() 不调用底层数据库。 它总是转到缓存服务器。 FromCacheOnly() 支持 Sum、Min 和 Max 等聚合函数。 但是,它也有 一些限制。 例如,FromCacheOnly() 不支持 LINQ 表达式中的多个投影或联接。
当然,最后两种方法也有异步替代方案。
插入项目
缓存 LINQ 查询的结果后,让我们看看如何插入项目。
在 MoviesController
类中,让我们编写一个新方法来添加电影。 像这样,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
// In the same MoviesController.cs file [HttpPost] public async Task Post([FromBody] AddMovie request) { var newMovie = new Movie( name: request.Name, releaseYear: request.ReleaseYear, rating: request.Rating); _database.Movies.Add(newMovie); await _database.SaveChangesAsync(); var options = new CachingOptions { StoreAs = StoreAs.SeperateEntities }; Cache cache = _database.GetCache(); cache.Insert(newMovie, out _, options); } |
像我们通常使用 SaveChangesAsync() 那样插入电影后,我们使用 GetCache() 获取对缓存的引用。 然后,使用相同的对象引用,我们通过传递 CachingOptions 的 Insert() 插入一个新电影。 我们还可以传递优先级、查询标识符和过期时间。
当我们使用 Insert() 时,如果缓存已经包含一个项目,它将被更新。
请注意,我们在调用 SaveChangesAsync() 之后立即将新项目插入到缓存中,而无需再次访问数据库来检索它然后缓存它。 这可以为我们要插入的每个对象节省一次到数据库的往返次数。
结论
这样我们就可以使用 NCache 在我们的 Entity Framework Core 应用程序中。 我们可以通过对现有 LINQ 查询进行一些更改来开始缓存实体。 我们只需要扩展我们的实体框架配置
并使用 FromCache() 及其替代方案。 在这篇文章中,我们缓存并插入了项目,但我们也可以 去掉 通过键名称、查询标识符或对象引用从我们的缓存中提取项目。
让我们记住,对于复杂的 LINQ 查询,让我们使用 FromCache()。 对于频繁更新的数据,让我们使用LoadIntoCache()。 对于只读数据,FromCacheOnly()。
除了我们在这篇文章中遵循的缓存旁路策略之外, NCache 支持其他缓存策略和模式,例如 Read-Through 和 Write-Through。 并与 ASP 集成.NET Core 支持会话状态缓存的框架。
要遵循我们在这篇文章中编写的代码,请查看我的 NCache 演示库 在GitHub上。