第十四节:EF Core性能优化

1.使用DbContext

在Core Mvc中,如果使用 AddDbContextPool 方法,那么在控制器请求 DbContext 实例时,我们会首先检查池中有无可用的实例。 请求处理完成后,实例的任何状态都将被重置,并且实例本身会返回池中。 从概念上讲,此方法类似于 ADO.NET 连接池的运行原理,并具有节约 DbContext 实例初始化成本的优势。
eg:

 services.AddDbContextPool<BloggingContext>( options => options.UseSqlServer(connectionString));

2.优先使用异步方法

EF Core 中提供了很多形如 xxxAsync 的异步方法,推荐使用这些方法提高吞吐量和性能,减少不必要的延时等待。

3.多活动结果集连接复用

多活动结果集 (MARS) 是一项允许对单个连接执行多个批处理的功能。 在以前的版本中,在单个连接上一次只能执行一个批处理。 使用 MARS 执行多个批处理并不意味着同时执行操作。 在连接字符串中添加:MultipleActiveResultSets=True 即可启用 MARS 特性。

详细见:https://docs.microsoft.com/zh-cn/dotnet/framework/data/adonet/sql/enabling-multiple-active-result-sets

4.批处理语句

EFCore中有一个重大改进,就是批处理,比如向数据库中增加n条数据(n>3),会组合成一次请求访问数据库(而在以前的EF中,不是批处理,增加几条,则会访问几次)。

注:操作数据条数 <=3 的时候,不会批处理,还是分多次请求,只有>3,才会批处理。

PS:可以手动设置批处理的条数MaxBatchSize,默认值很大。optionsBuilder.UseSqlServer("Server=localhost;Database=EFDB01;User ID=sa;Password=123456;", b => b.MaxBatchSize(10));

(1). 增加

 //1.增加 (3条及以下不合并,3条以上合并)
   for (int i = 0; i < 5; i++)
   {
       dbContext.Add(new T_UserInfor() { id = Guid.NewGuid().ToString("N"), userAge = i, addTime = DateTime.Now });
   }
   int count = dbContext.SaveChanges();

在这里插入图片描述
(2). 修改

//2.修改(3条及以下不合并,3条以上合并)
var list = dbContext.T_UserInfor.Take(5).ToList();
foreach (var item in list)
{
    item.userSex = "男111";
}
int count2 = dbContext.SaveChanges();

在这里插入图片描述

(3). 混合操作

//3.插入、更新、删除的混合操作 (3条及以下不合并,3条以上合并)
var list3 = dbContext.T_UserInfor.Take(2).ToList();
//增加
for (int i = 0; i < 2; i++)
{
    dbContext.Add(new T_UserInfor() { id = Guid.NewGuid().ToString("N"), userAge = i, addTime = DateTime.Now });
}
//更新
foreach (var item in list3)
{
    item.userAge = 12;
}
//删除
dbContext.Entry(list3.Take(1).FirstOrDefault()).State = EntityState.Deleted;
int count3 = dbContext.SaveChanges();

在这里插入图片描述

5.关闭状态追踪

跟踪行为决定了 EF Core 是否将有关实体实例的快照信息保留在其更改跟踪器中。 如果已跟踪某个实体,则该实体中检测到的任何更改都会在 SaveChanges() 期间永久保存到数据库。当决定只查询数据,不更改数据时,非跟踪查询十分有用,非跟踪查询的执行会更快,因为无需为查询实体设置快照跟踪信息。 如果不需要更新从数据库中检索到的实体,则应优先使用非跟踪查询。

(1).单体查询关闭:AsNoTracking()

(2).整个上下文关闭:context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;

6.关闭状态同步

当从数据库进行查询数据时,上下文便捕获了每个实体属性的快照(数据库值,原始值,当前值),当调用SaveChanges 时,在内部会自动调用 DetectChanges 方法,此方法将扫描上下文中所有实体,并比较当前属性值和存储在快照中的原始属性值,如果被找到的属性值发生了改变,此时EF将会与数据库进行交互,进行数据更新。会导致自动调用 DetectChanges 方法: Find、Local、Remove、Add、Update、Attach、SaveChangesEntry 等。 但是,自动同步状态会频繁调用,可手动关闭以上方法的自动同步,当数据都修改好后,一次性手动同步。

关闭:context.ChangeTracker.AutoDetectChangesEnabled = false;

开启:context.ChangeTracker.DetectChanges();

7.使用 EF.Functions.xxx 进行查询

(1).使用 EF.Functions.Like进行模糊查询要比 StartsWith、ContainsEndsWith 方法生成的SQL语句性能更优。

A. Contains语句,生成的sql为:

  var data3 = dbContext.T_UserInfor.Where(u => u.userName.Contains("p")).ToList();

用的是charindex
在这里插入图片描述
B. EF.Functions.Like语句生成的sql为:

  var data1 = dbContext.T_UserInfor.Where(u => EF.Functions.Like(u.userName, "%p%")).ToList();
  //或者
  var data2 = (from p in dbContext.T_UserInfor
               where EF.Functions.Like(p.userName, "%p%")
               select p).ToList();

用的是Like
在这里插入图片描述
PS:在传统的.Net中,还有种用法 SqlMethods,详见:https://www.cnblogs.com/yaopengfei/p/11805980.html

(2).还有EF.Functions.DateDiffDay (DateDiffHour、DateDiffMonth),求天、小时、月之间的数量

PS:在EF Core中StartsWithContainsEndsWith模糊查询实际分别被解析成为Left、CharIndexRight,而不是Like,而EF.Functions.Like会解析成Like语句。

详见:https://www.cnblogs.com/tdfblog/p/entity-framework-core-like-query.html

8.DbFunctionAttribute 标量函数

EF Core 支持映射数据库中定义的函数,可以在 LINQ 查询中使用,该功能支持将数据库标量函数映射到方法存根,使其可用于 LINQ 查询并转换为 SQL。 在 DbContext 上声明静态方法,并使用 DbFunctionAttribute 对其批注.

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
EF6 是 Entity Framework 6 的简称,它是微软开发的一种对象关系映射(ORM)工具。T-SQL 是 Transact-SQL 的简称,是一种用于 SQL Server 数据库的查询语言。 在 EF6 查询性能和 T-SQL 对比方面,有以下几点需要考虑: 1. 执行计划:EF6 会将 LINQ 查询转换为相应的 SQL 查询语句,然后由数据库服务器执行。而 T-SQL 直接在数据库服务器上执行,因此在执行计划的生成和优化方面,T-SQL 通常更加高效。 2. 数据库适应性:T-SQL 可以充分利用数据库的特性和优化策略,如索引、分区等。而 EF6 在生成 SQL 查询语句时,可能无法充分利用数据库的特性,导致性能较低。 3. 缓存机制:EF6 提供了查询结果的缓存机制,可以在一定程度上提高查询性能。而 T-SQL 没有内置的缓存机制,需要手动实现。 4. 查询表达能力:EF6 使用 LINQ 查询语法,提供了强类型的查询表达能力,可以更加直观和灵活地进行查询。而 T-SQL 的查询表达能力相对较弱,需要手动编写 SQL 查询语句。 综上所述,EF6 在查询性能方面可能不如 T-SQL,特别是在复杂查询和大数据量的情况下。如果对性能要求较高,可以考虑直接使用 T-SQL 编写查询语句。但是,EF6 提供了更方便和灵活的开发方式,并且在简单查询和开发效率方面具有优势。所以,在选择使用 EF6 还是 T-SQL 时,需要根据具体场景和需求进行权衡。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值