我正在研究Asp.Net Core 3.1 API。我在SQL Server数据库中有几个表。
我正在尝试使用InMemory数据库,并且试图在应用程序启动时将数据加载到这些表中。
我写了下面的代码。
public partial class MyContext : DbContext
{
public MyContext ()
{
}
public MyContext (DbContextOptions<MyContext > options)
: base(options)
{
}
public virtual DbSet<TestEntity> TestEntity{ get; set; }
...
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
optionsBuilder.UseInMemoryDatabase("name=RuleDB");
}
}
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<MyContext>(opt => opt.UseInMemoryDatabase("myDbName"));
appsettings.json
"ConnectionStrings": {
"RuleDB": "Server=tcp:xyz.database.windows.net,1433;Initial Catalog=myDB;Persist Security Info=False;User ID=test;Password=****;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30"
}
当我尝试执行context.TestEntity.ToList();
时,它没有显示记录。
我基本上是在应用程序启动时尝试将SQL Server数据库中的数据加载到InMemory数据库中。
我是否缺少任何步骤,这不是一个好方法(我是说应该使用InMemory缓存代替InMemory数据库)?
答案 0 :(得分:-1)
在StartUp.cs中,ConfigureServices引用
services.AddTransient<IEntityRepository, EntityRepository>();
services.AddTransient<IEntityService, EntityService>();
services.AddMemoryCache();
添加新的存储库界面。
public interface IEntityRepository
{
Task<List<Entity>> GetEntity();
}
添加一个将封装DbContext的新类,并实现接口
public class EntityRepository : IEntityRepository
{
private readonly DbContext _dbContext;
public(EntityRepository dbContext){
_dbContext = dbContext;
}
public async Task<List<Entity>> GetEntity()
{
return await _dbContext.Entity.ToListAsync();
}
}
添加另一个名为IEntityService的接口
public interface IEntityService
{
Task<List<Entity>> GetEntity();
}
添加另一个名为EntityService的类,封装缓存和存储库调用。
public class EntityService : IEntityService
{
private readonly IEntityRepository _repository;
private readonly IMemoryCache _cache;
public(EntityService repository, IMemoryCache cache){
_repository = repository;
_cache = cache
}
public async Task<List<Entity>> GetEntity()
{
var cacheKey = $"{anything-can-be-user-specific-too}";
return await _memoryCache.GetOrCreateAsync(cacheKey, x =>
{
var entities = _repository.GetEntity().GetAwaiter().GetResult();
x.SlidingExpiration = TimeSpan.FromSeconds(900);
x.AbsoluteExpiration = DateTime.Now.AddHours(1);
return Task.FromResult(entities);
});
}
}
我以示例为例的缓存策略表明,如果在10分钟内未引用该缓存(slidingRefresh),则该缓存将过期并被删除。可以将它与AbsoluteExpiration一起使用,这样您就可以在假设1小时后强制刷新缓存...
现在让IEntityService成为您的起点,假设您有一个控制器...
将服务注入控制器,例如
public class RandomController : ControllerBase
{
private readonly IEntityService _entityService;
public RandomController(IEntityService entityService)
{
_entityService = entityService;
}
[HttpGet]
[Route("randomroute")]
public async Task<IActionResult> GetEntities()
{
return Ok( await _entityService.GetEntity());
}
}
应用程序第一次执行时将引用数据库,但是所有后续调用(直到缓存策略到期)将引用内存缓存。
现在,如果要更改缓存的项目,可以引入新服务来执行数据库更新,然后通过使缓存键无效来强制进行缓存更新。
答案 1 :(得分:-1)
根据您的代码片段,当应用程序启动时,我没有找到将数据添加到内存数据库的位置。因此,我认为问题与之相关。
尝试引用以下文章将种子数据添加到数据库:
Applying Seed Data To The Database
Using EF Core's InMemory Provider To Store A "Database" In Memory