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);
}