在 Entity Framework Core 中优化查询:实现.NET 中的高性能数据访问

科技   2024-11-22 17:53   上海  


在现代 Web 应用程序中,数据访问在性能方面起着至关重要的作用。Entity Framework Core (EF Core) 是适用于 .NET 的常用 ORM(对象关系映射器),可简化数据库交互。但是,如果不有效使用,可能会导致性能瓶颈。在本文中,我们将探讨在 EF Core 中优化查询的关键策略,以确保应用程序平稳运行。

为什么查询优化很重要

在深入研究优化技术之前,必须了解为什么优化查询至关重要。低效的查询可能会导致:

  • 响应时间慢:长时间运行的查询可能会延迟响应,从而影响用户体验。

  • 资源消耗增加:低效的查询会消耗更多的 CPU、内存和 I/O 资源。

  • 数据库争用:优化不佳的查询可能会导致争用,从而导致数据库锁定并进一步降低性能。

优化 EF Core 查询的关键策略

  1. 将 AsNoTracking 用于只读查询

默认情况下,EF Core 会跟踪从数据库中检索到的实体,这在内存和 CPU 方面可能会很昂贵。如果您不需要更新这些实体,请使用 来禁用更改跟踪。AsNoTracking()

var customers = context.Customers.AsNoTracking().ToList();

这个简单的更改可以显著提高只读查询的性能。

2. 利用已编译的查询
EF Core 允许您编译查询,这些查询可以多次重复使用,而无需重新转换。编译的查询对于频繁执行的查询特别有用。

var getCustomers = EF.CompileQuery((MyDbContext ctx) =>  
ctx.Customers.Where(c => c.IsActive));
var activeCustomers = getCustomers(context).ToList();

编译查询可以减少将 LINQ 表达式转换为 SQL 的开销,从而加快执行速度。

3. 尽早
筛选数据始终尽早筛选数据,以最大程度地减少从数据库中检索的数据量。这减少了数据库和应用程序的负载。

var customers = context.Customers.Where(c => c.IsActive)  
.Select(c => new { c.Name, c.Email }).ToList();

在此示例中,仅检索具有姓名和电子邮件的活动客户,从而减少加载的数据量和内存占用。

4. 使用投影以避免加载不必要的数据

EF Core 允许您仅投影所需的字段,这可以减小结果集的大小。

var customerNames = context.Customers.Where(c => c.IsActive)  
.Select(c => c.Name).ToList();

此查询不会加载整个实体,而是仅检索客户名称,这可以显著减少传输的数据量。

5. 使用 Indexes 和 Include 语句
进行优化确保您的查询有效地利用索引。此外,用于在单个查询而不是多个查询中加载相关数据。Include()

var orders = context.Orders.Include(o => o.Customer)  
.Where(o => o.OrderDate >= DateTime.Today).ToList();

此方法在单个查询中检索订单及其关联的客户,从而减少数据库往返的次数。

6. 批量操作
执行批量操作时,请考虑使用批处理来减少数据库往返次数。

var customers=context.Customers.Where(c => c.IsActive).ToList();   
foreach (var customer in customers) {
customer.LastUpdated = DateTime.Now; }
context.SaveChanges();

此示例在单个批处理中更新多个客户,从而减少单个保存操作的开销。

实际示例:实际查询优化

让我们考虑一个真实场景,我们需要检索过去 30 天内下订单的活跃客户列表。我们将应用上面讨论的优化技术。

var activeCustomersWithRecentOrders = context.Customers  
.AsNoTracking()
.Include(c => c.Orders)
.Where(c => c.IsActive && c.Orders.Any(o => o.OrderDate >= DateTime.Now.AddDays(-30)))
.Select(c => new
{
c.Name,
c.Email,
RecentOrders = c.Orders.Where(o => o.OrderDate >= DateTime.Now.AddDays(-30))
})
.ToList();

在此优化的查询中:

  • 我们过去常常禁用更改跟踪,因为我们没有更新实体。AsNoTracking()

  • 我们仅包含过去 30 天的订单,以最大限度地减少数据检索。

  • 我们将数据投影到仅包含必要字段的形状中。

优化 EF Core 中的查询对于构建高性能 .NET 应用程序至关重要。通过使用禁用更改跟踪、编译查询、提前筛选数据和利用投影等技术,您可以显著提高应用程序的性能。请记住,优化的关键是了解应用程序的特定需求,并将这些策略应用于影响最大的地方。

如果你喜欢我的文章,请给我一个赞!谢谢

架构师老卢
资深软件架构师, 分享编程、软件设计经验, 教授前沿技术, 分享技术资源(每天发布电子书),每天进步一点点...
 最新文章