.NET 8 Blazor Server应用EF Core报错ReadAsync时阅读器已关闭的解决方法
解决方案:Invalid attempt to call ReadAsync when reader is closed.
针对你在.NET 8 Blazor Server中遇到的EF Core查询错误,以下是具体的修复建议:
1. 改用DbContext工厂模式注册上下文
Blazor Server的Scoped生命周期与电路绑定,直接注入Scoped的DbContext可能导致上下文实例被共享或提前释放。推荐使用DbContext工厂模式:
修改Program.cs中的DbContext注册代码:
// 替换原有的AddDbContext注册 builder.Services.AddDbContextFactory<EFCoreContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("CordobaLifeStyle")));
然后更新Repository类,注入IDbContextFactory<EFCoreContext>并在每次操作时创建新的上下文实例:
public class MenuRepository : IMenuRepository { private readonly IDbContextFactory<EFCoreContext> _contextFactory; public MenuRepository(IDbContextFactory<EFCoreContext> contextFactory) { _contextFactory = contextFactory; } public async Task<List<Menu?>> GetAll(CancellationToken cancellationToken) { using var context = _contextFactory.CreateDbContext(); return await context.Menu.ToListAsync(cancellationToken); } }
2. 正确传递CancellationToken
确保将CancellationToken传递给所有EF Core异步查询方法,避免因取消操作导致阅读器异常:
- 在Repository的查询方法中,将传入的token传递给
ToListAsync:
return await _context.Menu.ToListAsync(cancellationToken);
- 在Blazor页面调用时,使用组件内置的CancellationToken(组件销毁时自动触发取消),而非
CancellationToken.None:
List<Menu?> lstMenu = await menuRepository.GetAll(this.CancellationToken);
3. 检查数据库连接配置
确认appsettings.json中的连接字符串CordobaLifeStyle正确无误,能正常连接到SQL Server数据库。可以通过测试简单查询验证连接是否正常。
4. 验证实体配置
检查MenuConfiguration中的映射规则,确保实体与数据库表的映射关系正确,没有错误的导航属性或字段映射导致EF Core生成无效SQL。
5. 移除不必要的异常捕获
你的代码中存在多余的try-catch块(比如EFCoreContext的OnConfiguring、Repository的GetAll方法),这些捕获后直接抛出的代码会掩盖原始异常细节,建议移除不必要的try-catch,保留真正需要处理异常的逻辑。
内容的提问来源于stack exchange,提问作者Matías Alejandro Novillo
相关产品推荐
相关产品推荐

