gpt4 book ai didi

c# - 在 Asp.Net Core + EF Core 中缓存数据的模式?

转载 作者:太空狗 更新时间:2023-10-30 01:01:14 26 4
gpt4 key购买 nike

我有一个 Asp.Net Core + EF Core REST 服务。我为要调用 SP 的数据库创建了一个 DbContext 类。该方法看起来很像:

public IQueryable<xxx> Getxxxs()
{
return Set<xxx>().FromSql("pr_Getxxx");
}

这一切都有效,但是每次调用 SP 没有任何意义,因为 SP 返回的数据很少改变。我想让数据过时,比如说每 24 小时一次。

在 Core 中是否有一种首选模式?我看到他们有 .AddCaching 扩展方法,但它似乎会被注入(inject)到 Controller 中?那么它是 Controller 的缓存工作吗?我假设它是线程安全的,所以我不需要做任何锁定或类似的事情?似乎是一种竞争条件,如果一个线程正在检查该项目是否已加载到缓存中,另一个线程可能正在插入它,等等?

最佳答案

嗯,你可以申请 decorator pattern .它与 .NET Core 无关,只是一种通用模式。

public class MyModel
{
public string SomeValue { get; set; }
}

public interface IMyRepository
{
IEnumerable<MyModel> GetModel();
}

public class MyRepository : IMyRepository
{
public IEnumerable<MyModel> GetModel()
{
return Set<MyModel>().FromSql("pr_GetMyModel");
}
}

public class CachedMyRepositoryDecorator : IMyRepository
{
private readonly IMyRepository repository;
private readonly IMemoryCache cache;
private const string MyModelCacheKey = "myModelCacheKey";
private MemoryCacheEntryOptions cacheOptions;

// alternatively use IDistributedCache if you use redis and multiple services
public CachedMyRepositoryDecorator(IMyRepository repository, IMemoryCache cache)
{
this.repository = repository;
this.cache = cache;

// 1 day caching
cacheOptions = new MemoryCacheEntryOptions()
.SetAbsoluteExpiration(relative: TimeSpan.FromDays(1));
}

public IEnumerable<MyModel> GetModel()
{
// Check cache
var value = cache.Get<IEnumerable<MyModel>>("myModelCacheKey");
if(value==null)
{
// Not found, get from DB
value = repository.GetModel();

// write it to the cache
cache.Set("myModelCacheKey", value, cacheOptions);
}

return value;
}
}

由于 ASP.NET Core DI 不支持拦截器或装饰器,因此您的 DI 注册将变得更加冗长。或者使用支持装饰器注册的第三方 IoC 容器。

services.AddScoped<MyRepository>();
services.AddScoped<IMyRepository, CachedMyRepositoryDecorator>(
provider => new CachedMyRepositoryDecorator(
provider.GetService<MyRepository>(),
provider.GetService<IMemoryCache>()
));

这样做的好处是您可以清楚地分离关注点,并且可以通过将 DI 配置更改为

来轻松禁用缓存
services.AddScoped<IMyRepository,MyRepository>();

关于c# - 在 Asp.Net Core + EF Core 中缓存数据的模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40597911/

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