解决Blazor UI中Eager Loading导航属性显示为Null的问题
问题原因
核心问题在于**taskTypes被声明为IQueryable<TaskTypeModel>**,这是一个延迟执行的查询对象:
- 后台代码里的
foreach会触发EF Core立即执行查询,此时DbContext处于有效作用域,能正常加载Site导航属性。 - Blazor组件渲染时会再次遍历这个
IQueryable,但此时DbContext可能已被回收(比如Scoped生命周期的DbContext在组件初始化后超出作用域),导致查询无法重新执行,最终UI中taskType.Site显示为Null。
解决方案
将延迟执行的IQueryable转为已加载的内存集合,同时改用异步生命周期方法避免阻塞:
- 调整字段类型为内存集合:
List<TaskTypeModel>? taskTypes;
- 替换同步初始化方法为异步,立即加载数据:
[Inject] public ApplicationDbContext dbContext { get; set; } = default!; protected override async Task OnInitializedAsync() { taskTypes = await dbContext.TaskTypes.Include(t => t.Site).ToListAsync(); // 验证数据(可选) foreach (var taskType in taskTypes) { Console.WriteLine(taskType.Site.Name); } }
- 修正UI中的值绑定(原代码是字符串字面量,不是绑定表达式):
<MudSelect T="string"> @if (taskTypes != null) { @foreach (var taskType in taskTypes) { <MudSelectItem Value="@taskType.Site.Name">@taskType.Site.Name</MudSelectItem> } } </MudSelect>
额外说明
- EF Core的
IQueryable仅在枚举(如foreach、ToList、Count等)时才会真正执行数据库查询。 - Blazor的Scoped服务(默认DbContext)生命周期与组件绑定,异步方法能更好适配EF Core的异步操作,避免DbContext提前释放。
- 确保
SiteModel在DbContext中正确配置了导航关系,避免实体配置问题导致Include失效。
内容的提问来源于stack exchange,提问作者david
相关产品推荐
相关产品推荐

