You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从Entity Framework异步创建IEnumerable?Blazor DevExpress组件相关疑问

1. 关于扩展方法无需声明为async的理解是否正确?

完全正确。context.Skills.OrderBy(s => s.Name)返回的是IQueryable<Skill>(它实现了IEnumerable<Skill>接口),这仅仅是构建了查询表达式树,并没有触发实际的数据库操作。只有当后续枚举这个集合(比如组件渲染遍历数据、调用ToList()等)时,才会执行数据库查询。只有真正执行数据库读写的操作(如ToListAsync()、FirstOrDefaultAsync()这类直接触发查询的方法),才需要用async/await标记异步。


2. Blazor Server + DevExpress组件的异步加载方案

有没有办法实现异步?

有两种可行的方案:

  • 提前在页面生命周期异步加载数据:
    在Blazor页面的生命周期方法(比如OnInitializedAsync)中,先异步获取数据并存到本地变量,再将变量传给组件的Data属性。示例代码:
    private List<Skill> _skills = new();
    
    protected override async Task OnInitializedAsync()
    {
        _skills = await NoTrackingDbContext.Skills.OrderBy(s => s.Name).ToListAsync();
        await base.OnInitializedAsync();
    }
    
    组件部分修改为:
    <DxFormLayoutItem Caption="Your skills:" Field="@nameof(RegisterPageModel.Skills)" ColSpanMd="6">
        <DxTagBox Data="@_skills"
                  TextFieldName="@nameof(Skill.Name)"
                  @bind-Values="@RegisterPageModel.Skills"/>
    </DxFormLayoutItem>
    
  • 使用DevExpress的异步数据绑定属性:
    若你的DevExpress版本支持,部分控件提供了DataAsync属性,可以直接传入异步方法:
    <DxFormLayoutItem Caption="Your skills:" Field="@nameof(RegisterPageModel.Skills)" ColSpanMd="6">
        <DxTagBox DataAsync="@(() => NoTrackingDbContext.Skills.OrderBy(s => s.Name).ToListAsync())"
                  TextFieldName="@nameof(Skill.Name)"
                  @bind-Values="@RegisterPageModel.Skills"/>
    </DxFormLayoutItem>
    

是否应该这么做?

非常推荐使用异步加载。Blazor Server的主线程负责处理用户交互,如果同步执行数据库查询,会阻塞主线程,导致页面失去响应(用户操作无反馈),尤其是查询耗时较长时,体验会极差。异步操作能释放主线程处理其他请求,提升应用的并发能力和响应性。

异步调用的优势

在Blazor Server场景下,异步加载的优势很明确:

  • 避免UI阻塞:用户不会看到“假死”的页面,还可以配合加载指示器优化体验。
  • 优化服务器资源:服务器可以同时处理更多用户请求,不会因单个同步查询占用线程。

内容的提问来源于stack exchange,提问作者David Thielen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 21:10:02