欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 国际 > EF Core 异步方法

EF Core 异步方法

2025/3/31 9:01:49 来源:https://blog.csdn.net/lei1083929965/article/details/146509077  浏览:    关键词:EF Core 异步方法

文章目录

  • 前言
  • 一、为什么使用异步方法
  • 二、核心异步方法
    • 1)查询数据
    • 2)保存数据
    • 3)事务处理
  • 三、异步查询最佳实践
    • 1)始终使用 await
    • 2)组合异步操作
    • 3)并行查询(谨慎使用)
  • 四、异常处理
  • 五、性能注意事项
    • 1)DbContext 生命周期
    • 2)取消操作支持
    • 3)禁用跟踪(只读场景)
  • 六、常见错误
    • 1)混合同步/异步调用
    • 2)未正确处理上下文
  • 七、高级模式
    • 1)批量操作
    • 2)原始 SQL 查询
  • 总结
    • EF Core 的异步方法通过以下方式提升性能:
    • 关键要点:


前言

在 Entity Framework Core 中,异步方法是优化数据库操作性能、避免阻塞线程的关键工具,特别适用于 Web 应用、API 或其他高并发场景。


一、为什么使用异步方法

  1. 避免线程阻塞:异步操作释放当前线程(如 ASP.NET 的请求线程),提高吞吐量。
  2. 提升响应性:在 UI 应用(如 WPF、MAUI)中防止界面卡死。
  3. 高效利用资源:适合长时间运行的数据库操作(如复杂查询、批量写入)。

二、核心异步方法

EF Core 为常见操作提供了异步版本,需结合 async/await 使用:

1)查询数据

  1. ToListAsync():异步返回列表
  2. FirstOrDefaultAsync():异步获取首个匹配项
  3. SingleOrDefaultAsync():异步获取唯一匹配项
  4. CountAsync():异步统计数量
  5. AnyAsync():异步检查是否存在
public async Task<List<Person>> GetActivePersonsAsync()
{using var context = new MyDbContext();return await context.Persons.Where(u => u.Name=="Tom").ToListAsync(); // 异步执行查询
}

2)保存数据

  1. SaveChangesAsync():异步提交更改
  2. AddAsync():异步添加单个实体(通常用于值生成策略)
public async Task CreatePersonsAsync(Person person)
{using var context = new MyDbContext();await context.Persons.AddAsync(person); // 异步添加await context.SaveChangesAsync();    // 异步提交
}

3)事务处理

public async Task TransferMoneyAsync(int fromId, int toId, decimal amount)
{using var context = new MyDbContext();using var transaction = await context.Database.BeginTransactionAsync();try{var fromAccount = await context.Accounts.FindAsync(fromId);var toAccount = await context.Accounts.FindAsync(toId);fromAccount.Balance -= amount;toAccount.Balance += amount;await context.SaveChangesAsync();await transaction.CommitAsync();}catch{await transaction.RollbackAsync();throw;}
}

三、异步查询最佳实践

1)始终使用 await

// ✅ 正确
var persons = await context.Persons.ToListAsync();// ❌ 错误(立即阻塞线程)
var persons = context.Persons.ToListAsync().Result;

2)组合异步操作

public async Task<Person> GetPersonWithOrdersAsync(int personId)
{return await context.Persons.Include(u => u.Orders).FirstOrDefaultAsync(u => u.Id == personId);
}

3)并行查询(谨慎使用)

var task1 = context.Persons.CountAsync();
var task2 = context.Orders.CountAsync();await Task.WhenAll(task1, task2);var totalPersons = task1.Result;
var totalOrders = task2.Result;

四、异常处理

try
{await context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException ex)
{// 处理并发冲突
}
catch (DbUpdateException ex)
{// 处理更新错误
}

五、性能注意事项

1)DbContext 生命周期

  1. 确保在 using 块或依赖注入范围内使用,避免内存泄漏。

2)取消操作支持

  1. 多数异步方法接受 CancellationToken

    var cts = new CancellationTokenSource();
    var users = await context.Persons.ToListAsync(cts.Token);
    

3)禁用跟踪(只读场景)

var persons = await context.Persons.AsNoTracking().ToListAsync();

六、常见错误

1)混合同步/异步调用

// ❌ 危险!可能导致死锁
public Person GetPerson(int id)
{return context.Persons.FirstOrDefaultAsync(u => u.Id == id).Result;
}

错误修正(修正为异步方法)

  1. 始终优先使用 async/await,避免 .Result 或 .Wait()
public async Task<Person> GetPersonAsync(int id)
{return await context.Persons.FirstOrDefaultAsync(u => u.Id == id);
}

2)未正确处理上下文

// ❌ 上下文可能被提前释放
public async Task<List<Person>> GetPersonsAsync()
{using var context = new MyDbContext();return await context.Persons.ToListAsync(); 
} // 上下文在此处释放,返回的实体可能无法延迟加载

错误修正(将原始代码改为安全模式)

  1. 优先使用 DTO 或投影
    避免直接返回实体,尤其是在 Web API 中。
  2. 明确加载关联数据
    使用 IncludeSelect 确保所有需要的数据已加载。
  3. 默认禁用跟踪
    在只读场景中,始终使用 AsNoTracking 提升性能。
  4. 严格管理 DbContext 生命周期
    Web 应用中,通过依赖注入(Scoped 生命周期)管理 DbContext
    桌面应用中,确保 DbContext 生命周期与 UI 操作同步。
// ✅ 安全:返回 DTO,无需延迟加载
public async Task<List<PersonDto>> GetPersonsAsync()
{using var context = new MyDbContext();return await context.Persons.Select(p => new PersonDto {Id = p.Id,Name = p.Name}).AsNoTracking().ToListAsync(); 
}

七、高级模式

1)批量操作

await context.BulkInsertAsync(entities); // 使用 EF Plus 等扩展库

2)原始 SQL 查询

var persons = await context.Persons.FromSqlInterpolated("SELECT * FROM T_Persons WHERE Age > {0}", 18).ToListAsync();

总结

EF Core 的异步方法通过以下方式提升性能:

  1. 减少线程阻塞
  2. 提高服务器吞吐量
  3. 优化资源利用率

关键要点:

  1. 始终 await 异步方法
  2. 正确处理上下文生命周期
  3. 结合 CancellationToken 实现可控取消
  4. 避免混合同步/异步代码

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词