Working with Redis and Entity Framework Core. Error: There is already an open DataReader associated with this Connection which must be closed first
Working with Redis and Entity Framework Core. Error: There is already an open DataReader associated with this Connection which must be closed first
我正在尝试为我的 API 使用 Redis。这就是问题所在。
我正在尝试这个:
[HttpGet]
public async Task<ActionResult<IEnumerable<Writer>>> GetAllWriters([FromServices] IWriterRepository repository, [FromServices] IDistributedCache cache)
{
string recordKey = "Writers_" + DateTime.Now.ToString("yyyyMMdd_hhmm");
var writers = await cache.GetRecordAsync<IEnumerable<Writer>>(recordKey);
if (writers == null)
{
writers = repository.GetAll();
await cache.SetRecordAsync(recordKey, writers, TimeSpan.FromSeconds(180));
}
return Ok(writers);
}
但我遇到了错误
There is already an open DataReader associated with this Connection which must be closed first.
我对这个错误有点困惑,因为 EF 调用可以获取我的数据,我可以将这些数据保存到 redis,我也“可以”从中取回数据,只需要弄清楚私有集的 SOLID 问题呵呵。
我愿意接受建议 :D.
这里是redis的实现
using System;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Distributed;
namespace Worthix.Api.Extensions
{
public static class DistributedCacheExtensions
{
public static async Task SetRecordAsync<T>(this IDistributedCache cache,
string recordId, T data, TimeSpan? absoluteExpireTime = null, TimeSpan? unusedExpireTime = null)
{
var options = new DistributedCacheEntryOptions();
options.AbsoluteExpirationRelativeToNow = absoluteExpireTime ?? TimeSpan.FromSeconds(60);
options.SlidingExpiration = unusedExpireTime;
var jsonData = JsonSerializer.Serialize(data);
await cache.SetStringAsync(recordId, jsonData, options);
}
public static async Task<T> GetRecordAsync<T>(this IDistributedCache cache, string recordId)
{
var jsonData = await cache.GetStringAsync(recordId);
if (jsonData == null)
return default(T);
return JsonSerializer.Deserialize<T>(jsonData);
}
}
}
和他的创业公司
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers().AddNewtonsoftJson(options =>
options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
// services.AddDbContext<DataContext>(opt => opt.UseInMemoryDatabase("database"));
services.AddDbContext<DataContext>(opt => opt.UseSqlServer(Configuration.GetConnectionString("connectionString")));
services.AddScoped<IWriterRepository, WriterRepository>();
services.AddTransient<IBookRepository, BookRepository>();
services.AddTransient<WriterHandler, WriterHandler>();
services.AddTransient<BookHandler, BookHandler>();
services.AddStackExchangeRedisCache(opt =>
{
opt.Configuration = Configuration.GetConnectionString("connectionStringRedis");
opt.InstanceName = "Worthix_";
});
}
我希望有足够的信息。
只是更新。
我明白了。我仍然不知道为什么会出现此错误。
我将 EF Core 查询重构为异步并且它有效,如果有人知道为什么会发生此错误,我会标记为正确答案。
[HttpGet]
public async Task<ActionResult<IEnumerable<Writer>>> GetAllWriters([FromServices] IWriterRepository repository, [FromServices] IDistributedCache cache)
{
string recordKey = "Writers_All_" + DateTime.Now.ToString("yyyyMMdd_hhmm");
var writersModel = await cache.GetRecordAsync<IEnumerable<WriterModel>>(recordKey);
if (writersModel == null)
{
var writers = await repository.GetAll();
await cache.SetRecordAsync(recordKey, writers);
return Ok(writers);
}
return Ok(writersModel);
}
我正在尝试为我的 API 使用 Redis。这就是问题所在。
我正在尝试这个:
[HttpGet]
public async Task<ActionResult<IEnumerable<Writer>>> GetAllWriters([FromServices] IWriterRepository repository, [FromServices] IDistributedCache cache)
{
string recordKey = "Writers_" + DateTime.Now.ToString("yyyyMMdd_hhmm");
var writers = await cache.GetRecordAsync<IEnumerable<Writer>>(recordKey);
if (writers == null)
{
writers = repository.GetAll();
await cache.SetRecordAsync(recordKey, writers, TimeSpan.FromSeconds(180));
}
return Ok(writers);
}
但我遇到了错误
There is already an open DataReader associated with this Connection which must be closed first.
我对这个错误有点困惑,因为 EF 调用可以获取我的数据,我可以将这些数据保存到 redis,我也“可以”从中取回数据,只需要弄清楚私有集的 SOLID 问题呵呵。
我愿意接受建议 :D.
这里是redis的实现
using System;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Distributed;
namespace Worthix.Api.Extensions
{
public static class DistributedCacheExtensions
{
public static async Task SetRecordAsync<T>(this IDistributedCache cache,
string recordId, T data, TimeSpan? absoluteExpireTime = null, TimeSpan? unusedExpireTime = null)
{
var options = new DistributedCacheEntryOptions();
options.AbsoluteExpirationRelativeToNow = absoluteExpireTime ?? TimeSpan.FromSeconds(60);
options.SlidingExpiration = unusedExpireTime;
var jsonData = JsonSerializer.Serialize(data);
await cache.SetStringAsync(recordId, jsonData, options);
}
public static async Task<T> GetRecordAsync<T>(this IDistributedCache cache, string recordId)
{
var jsonData = await cache.GetStringAsync(recordId);
if (jsonData == null)
return default(T);
return JsonSerializer.Deserialize<T>(jsonData);
}
}
}
和他的创业公司
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers().AddNewtonsoftJson(options =>
options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
// services.AddDbContext<DataContext>(opt => opt.UseInMemoryDatabase("database"));
services.AddDbContext<DataContext>(opt => opt.UseSqlServer(Configuration.GetConnectionString("connectionString")));
services.AddScoped<IWriterRepository, WriterRepository>();
services.AddTransient<IBookRepository, BookRepository>();
services.AddTransient<WriterHandler, WriterHandler>();
services.AddTransient<BookHandler, BookHandler>();
services.AddStackExchangeRedisCache(opt =>
{
opt.Configuration = Configuration.GetConnectionString("connectionStringRedis");
opt.InstanceName = "Worthix_";
});
}
我希望有足够的信息。
只是更新。
我明白了。我仍然不知道为什么会出现此错误。
我将 EF Core 查询重构为异步并且它有效,如果有人知道为什么会发生此错误,我会标记为正确答案。
[HttpGet]
public async Task<ActionResult<IEnumerable<Writer>>> GetAllWriters([FromServices] IWriterRepository repository, [FromServices] IDistributedCache cache)
{
string recordKey = "Writers_All_" + DateTime.Now.ToString("yyyyMMdd_hhmm");
var writersModel = await cache.GetRecordAsync<IEnumerable<WriterModel>>(recordKey);
if (writersModel == null)
{
var writers = await repository.GetAll();
await cache.SetRecordAsync(recordKey, writers);
return Ok(writers);
}
return Ok(writersModel);
}