您当前所在位置: > 爆料站 > 有深度

彻底征服EntityFrameworkCore优化!

时间:2019-09-16 09:04:00  来源:  作者:网络

原标题:彻底征服 Entity Framework Core 优化!

作者 | 喵叔

责编 | 胡巍巍

出品 | CSDN(ID:CSDNnews)

这篇文章我们来讲解一下 Entity Framework Core 的优化方案。Entity Framework Core 是微软针对跨平台开发推出的 ORM 框架,继承了 Entity Framework 的众多优点,也对 Entity Framework 中的不足进行了优化和补充。

虽然 Entity Framework Core 进行了性能上的优化,但是这些在进行大量数据库操作的时候依然存在性能问题。

针对Entity Framework Core 的性能优化方案,不仅可以使用 Entity Framework 大部分的优化方案,还有一套专门针对 Entity Framework Core 的优化方案。 现在我们就来具体讲解一下针对 Entity Framework Core 的优化方案。

零、禁用实体追踪

当我们从数据库中查询出数据时,上下文就会创建实体快照,从而追踪实体。在调用 SaveChanges 时,实体有任何更改都会保存到数据库中。

但是当我们只需要查询出实体而不需要修改时(只读),实体追踪就没有任何用途了。这时我们就可以调用 AsNoTracking 获取非追踪的数据,这样可以提高查询性能。具体代码如下:

`using(vardb = newEFCDbContext)

{

varusers = db.Users.AsNoTracking.ToList;

}

Entity Framework Core 默认使用的是快照式便跟追踪,因此我们可以通过 ChangeTracker 来关闭 DetectChanges 来提高性能。我们来看一下具体的例子:

public override int SaveChanges(bool acceptAllChangeOnSuccess)

{

ChangeTracker.DetectChanges;

foreach(varentry inChangeTracker.Entries.Where(p=>p.State==EntityState.Added))

{

this.AddRange(entry.Entity);

}

ChangeTracker.AutoDetectChangesEnabled = false;

varresult = base.SaveChanges(acceptAllChangeOnSuccess);

ChangeTracker.AutoDetectChangesEnabled = true;

returnresult;

}

上述代码,我们重写了 SaveChanges 方法,通过 ChangeTracker.AutoDetectChangesEnabled = false;代码关闭了变更追踪,然后调用 Entity Framework Core 的 SaveChanges 方法保存数据,最后再次调用 ChangeTracker.AutoDetectChangesEnabled = true; 来开启变更追踪。这样一来 Entity Framework Core 的最终性能得到了优化。

下面我们来思考一个问题,当需要多表关联查询的时候,我们应该怎么优化查询性能?

这时你一定会想到使用前面所说的 AsNoTracking 方法,那么我们就把你想到的这个方法以代码的形式展示出来:

using(vardb = newEFCDbContext)

{

varuser = fromu indb.Users.AsNoTracking

joino indb.Orders.AsNoTracking

onu.Id equalso.UserId

selectu;

}

看到上述代码,你第一感受是什么?每个表都要写一个 AsNoTracking 方法,很麻烦吧?代码很长吧?可读性很低吧?

那么怎么来解决呢?Entity Framework Core 给我们提供了一个很好的就觉方案,就是通过上下问设置跟踪行为为 AsNoTracking 。

using(vardb = newEFCDbContext)

{

db.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;

varusers = db.Users;

varorders = db.Orders;

varuser = fromu inUsers

joino inorders

onu.Id equalso.UserId

selectu;

}

优化模糊查询

模糊查询在开发过程中经常用到,比如查询姓名、电话号码、邮箱等等都会用到模糊查询。

我们也知道模糊查询会造成全表扫描的问题,因此 Entity Framework Core 专门针对模糊查询进行了一番优化,出现了 EF.Functions.Like 方法。我们可以利用这个特性来自定义模糊查询。Like 方法有两个重载:

1. 自定义匹配模式

举个例子来讲解这个重载的使用方法,例如我们需要查询出姓名中包含 燕 的人员,我们可以这么写:

using (vardb = newEFCDbContext)

{

varusers =db.Users;

varuser = users.Where(p=>EF.Functions.Like(p.Name,"%燕%")).ToList;

}

2. 将转义字符当作普通字符

当我们传递的查询参数包含转义字符时,我们可以使用这个重载来将转义字符转换为普通字符来处理:

`using (vardb = newEFCDbContext)

{

varusers =db.Users;

varuser = users.Where(p=>EF.Functions.Like(p.Name,@"%燕%",@"")).ToList;

}

自定义标量函数

Entity Framework Core 有一个重要特性就是自定义标量函数。

自定义标量函数可以将数据库中的标量函数映射到类中的方法,并且在使用 LINQ 查询时会用到。

自定义标量函数为我们提供了一个快捷创建方法,并在方法上应用 DbFunctionAttribute 属性。

DbFunctionAttribute 属性可以将静态方法映射到数据库函数。

默认情况下数据库函数中的静态方法名必须相同,我们也可以通过 DbFunctionAttribute 属性来指定不同的名称。在创建自定义标量函数的时候我们必须遵循如下两个要求:

1. 函数必须是静态方法,而且在上下文中声明;

2. 只能作为参数标量值返回。

下面我们来看一下如何在上下文中定义标量函数:

[DbFunction(FunctionName="DbFunction",Schema="dbo")]

public static string MyFunction(string name)

{

//more code

}

上述代码中我们定义了 MyFunction 方法映射进数据库中的标量函数名称 DbFunction,并且也定义了使用数据库的架构名称 dbo。

如果自定义标量函数方法没有在上下文中定义,我们还可以在 OnCinfiguring 方法中利用 HasDbFunction 方法通过反射获取自定义标量函数。我们将上面的代码改造一下来看看:

modelBuilder.HasDbFunction(this.GetType.GetMeth("MyFunction"),options=>

{

options.HasName("DbFunction");

options.HasSchema("dbo");

})

注意:函数使用数据库架构的名称是必须存在的,否则将会抛出异常。

讲了这么多我们来看一下自定义标量函数到底该怎么优化性能。我们都知道 Entity Framework Core 不支持将 LINQ 中的 Min、Max、Average 等函数翻译成SQL查询,只会在本地执行查询,我们可以通过自定义标量函数来使 Min、Max、Average 等函数在远端执行查询。下面我们通过例子来看一下:

首先定义自定义标量函数:

publicstaticclassFunctionDemoClass

{

publicstaticvoidDemoAverage(thisEFCDbContext db)

{

using(vartransaction = db.Database.BeginTransaction)

{

try

{

db.Database.ExecuteSqlCommand("IF OBJECT ID ('dbo.DemoAverage',N'FN') IS NOT NULL DROP FUNCTION db0.DemoAverage");

db.Database.ExecuteSqlCommand("CREATE FUNCTION DemoAverage (@UserId int) RETURNS FLOAT "+

@"AS BEGIN

DECLARE @result AS FLOAT

SELECT @result AVG(CAST(ScoreAvg AS FLOAT)) FROM db.Score as s WHERE s.UserId=@UserId

RETURN @result END");

transaction.Commit;

}

catch(Exception ex)

{

throwex;

}

}

}

}

接着我们在上下文中进行映射:

`publicstaticfloat? DemoAverage(intuserId)

{

// more code

}

protected override void OnModelCreating(ModelBuilder modelBuilder)

{

modelBuilder.HasDbFunction(=>DemoAverage(default(int).HasSchema(dbo)));

base.OnModelCreating(modelBuilder);

}

通过这种方法我们将计算平均值的工作交给了数据库,这样就可以提高 Entity Framework Core 的查询速度。

显式编译查询

显式编译查询也是 Entity Framework Core 的重要特性,主要用在提供高可用的场景下。

默认情况下 Entity Framework Core 使用查询表达式的散列来表示自动编译和缓存查询,如果代码需要重用 Entity Framework Core 将会使用用哈希查找从缓存中返回已编译的查询。

但是散列计算和高速缓存查找也会带来性能问题,这时我们就需要抛弃散列计算和高速缓存查找。

Entity Framework Core 已经为我们想到了这一点,我们只需要调用 Entity Framework Core 静态类中使用以下方法即可:

  • EF.CompileQuery
  • EF.CompileAsyncQuery

上述方法的第一个参数必须是上下文,第二个参数类型不限。小提示:上述两个方法的第二个参数数量一共有8个。

我们依然通过例子来讲解一下:

using (var_db = newEFCDbContext)

{

varquery = EF.CompileQuery(

(EFCDbContext db ,int id)=>db.Users.FirstOrDefault(p=>p.Id==id)

);

User user1 = query(_db,123);

User user2 = query(_db,123);

}

上述代码知识展示了显示编译查询的使用方法,这段代码并不能真实的反映出显示编译查询的优点。

当我们同时进行上万次查询的时候就会发现 Entity Framework Core 的性能有显著提升。因此当查询频繁访问时,我们就可以使用显示编译查询来提高查询性能。小提示:显示编译查询的执行速度是常规模式的2倍。

上下文实例池

Entity Framework Core 增加了上下文连接池的概念,可以在依赖注入中注册 DbContext 来创建一个可重用的 DbContext 实例池。

也就是说每次请求都会从实例池中提取一个实例,而不是重新创建一个实例,这样有利于程序性能的提高。默认情况下上下文实例池有128个实例,但是我们可以通过配置来改变默认值。

我们可以使用 AddDbContextPool 方法在依赖注入中注册 DbContext 类。方法接收 DbContextOptionBuilder 用于定义链接字符串,第二个参数时实例池最大的实例数值。我们需要在 Startup 类的 ConfigureServices 方法中定义。

代码如下:

public void ConfigureServices(IServiceCollection services)

{

varconStr="连接字符串";

services.AddDbContextPool<EFCDbContext>(options=>{

options.UseSqlServer(conStr,p=>p.MigrationAssembly(this.GetType.GetTypeInfo.Assembly.FullName));

},1000);

}

上述代码中我们定义的上下文实力数量最大时1000,当请求数量超过1000时,Entity Framework Core 将会为后续的请求创建新的上下文实例,而不是从实例池中获取。

因此设置最大实力数量只是限制了 Entity Framework Core 实例池中实例的数量,而不是限制上下文实例的总数。

总结

上述几方面就是针对 Entity Framework Core 的性能优化,我不建议使用上下文实例池的方式,就如同我结尾所说的那样最大实力数量只不过是限制了实力池中实例的数量,一旦请求超过实力池中最大的实力数量,将会创建新的实例,而不是排队等候。

作者简介:朱钢,笔名喵叔,CSDN博客专家,.NET高级开发工程师,7年一线开发经验,参与过电子政务系统和AI客服系统的开发,以及互联网招聘网站的架构设计,目前就职于北京恒创融慧科技发展有限公司,从事企业级安全监控系统的开发。游戏网

责任编辑:

相关下载

玩家评论

日本美女Enako Cos《七大罪》 酥胸微露长腿吸睛

今日小编为大家带来的是日本美女Coser Enako的Cos新作品。最近她接受《周刊少年マガジン》邀请,Cos了《七大罪》两位女主角伊丽莎白和戴安娜。enako穿上Cos详情>>

阅读: 9
日期: 2019-10-09
绝地求生:PKL竞争激烈 EntusF单日三鸡反超SKT 多队争抢一个席位

原标题:绝地求生:PKL竞争激烈 EntusF单日三鸡反超SKT 多队争抢一个席位 绝地求生韩国PKL联赛已经进入白热化阶段,虽然握有六个PGC名额,但各支队伍的竞争详情>>

阅读: 7
日期: 2019-10-09
映卓ENJOVP“蒸”战黄金周助玩家放飞自我_电子

原标题:映卓ENJOVP“蒸”战黄金周 助玩家放飞自我 国庆黄金周已经进入倒计时,不少人都已规划好出行计划。据文化和旅游部消息,2018年国庆假期全国详情>>

阅读: 8
日期: 2019-10-08
[ESL One纽约站]G2两度逆转击败ENCE

原标题:[ESL One纽约站]G2两度逆转击败ENCE 导读:G2两度逆转击败ENCE。 在昨天凌晨进行的ESL One纽约站A组开局赛中,G2战队在BO3中2-0逆转击败了ENCE详情>>

阅读: 8
日期: 2019-09-27
极限之地印度赛区EntityGaming晋级亚洲总决赛

  2019年ZOWIE GEAR极限之地CSGO亚洲公开赛南亚赛区决赛昨日落下帷幕,Entity Gaming在先丢一局的情况下,连追两把,成功获得上海亚洲总决赛的入场券详情>>

阅读: 19
日期: 2019-09-23
一大波万代冷饭?万代注册一批含Encore商标

原标题:一大波万代冷饭?万代注册一批含Encore商标 据外媒Gematsu报道,万代南梦宫近日注册了多个名称中包含“Encore”的商标,鉴于此前万代南梦详情>>

阅读: 27
日期: 2019-09-18
万代南梦宫注册数款Encore商标《风之克罗诺亚》或推出高清版

原标题:万代南梦宫注册数款Encore商标《风之克罗诺亚》或推出高清版 万代南梦宫于9月4日在日本申请了一大堆商标,这些商标于今日进行了公开,其中详情>>

阅读: 19
日期: 2019-09-18
重启经典之作?万代南梦宫注册多个“Encore”系列商标

原标题:重启经典之作?万代南梦宫注册多个“Encore”系列商标 近日,万代南梦宫被发现注册了一大堆以“Encore”系列商标,《钻地小子 Encore》《风之详情>>

阅读: 24
日期: 2019-09-17
万代南梦宫注册数款Encore商标 《风之克罗诺亚》或推出高清版

_contentraw">万代南梦宫于9月4日在日本申请了一大堆商标,这些商标于今日进行了公开,其中包含《钻地小子Encore》《风之克罗诺亚Encore》《源平讨魔传Encore》《瓦强世界Encor详情>>

阅读: 10
日期: 2019-09-17
万代注册多个Encore商标 或暗示重启经典之作

根据最新消息,万代南梦宫近期注册了一大批以Encore为结尾的新商标,熟悉万代南梦宫作品的玩家可能会联想到与之相关的作品,从此次注册的商标内容来看,一些人猜测详情>>

阅读: 11
日期: 2019-09-17
万代注册多个Encore商标或暗示重启经典之作

原标题:万代注册多个Encore商标 或暗示重启经典之作 根据最新消息,万代南梦宫近期注册了一大批以Encore为结尾的新商标,熟悉万代南梦宫作品的玩家详情>>

阅读: 14
日期: 2019-09-17
OPPO将音乐的天赋带到了耳机市场,带来EncoQ1无线降噪耳机

原标题:OPPO 将音乐的天赋带到了耳机市场,带来 Enco Q1 无线降噪耳机 OPPO 今日发布了全新的 Reno 2,但还有一个配角同期登场,那就是 OPPO Enco Q1 无详情>>

阅读: 12
日期: 2019-09-10
【猫神】Enlightenment 完结 3打1都大不多 会不会玩游戏

【猫神】Enlightenment 完结 3打1都大不多 会不会玩游戏详情>>

阅读: 30
日期: 2019-09-09
细览EngineeredGarmentsxHOKAONEONE,这次依旧下单?

原标题:细览Engineered Garments x HOKA ONE ONE,这次依旧下单? 日系品牌 Engineered Garments 发布 2020 春夏系列之后,对于整个系列的期待可不止搭详情>>

阅读: 31
日期: 2019-09-09
鬼魂搜索仪EntitySensorPro-EMFDetector

世界上到底有没有鬼?让科学来告诉你。也许真如有些人所言,鬼与我们生存在不同维度的世界,肉眼不能发现,却可以通过它们对我们周围磁场的影响找到它们。这款鬼魂搜索仪就是利用的详情>>

阅读: 0
日期: 2019-09-07
EndlessMadness

EndlessMadness是一款最近刚上线的手绘风格的动作闯关类游戏,游戏的玩法简单,画风黑暗,在这个游戏中玩家需要控制自己的角色不断的在黑暗中前进,躲避路上的各种陷阱和障碍,收集路详情>>

阅读: 0
日期: 2019-09-06
Endhall英文版

《Endhall》是一款小型回合制roguelike玩法的游戏,你需要控制一名能喷电吐火的小机器人在神秘的地牢中进行无尽的冒险,这里有着大量的邪恶机器人在等待着你,在规定时间内你可以详情>>

阅读: 0
日期: 2019-09-06
Entity中文版

游戏简介《Entity》是一款惊悚向解密冒险小游戏,故事讲述的是在荒废的无名森林深处,有一座名为Shellmond的病院,在那里似乎存在什么排斥生者的东西,因为传言中进入到那里的人没详情>>

阅读: 0
日期: 2019-09-06
ENIGMA:英文版

游戏简介《ENIGMA:》是由Uzumeya制作,FruitbatFactory发行的一款文字冒险游戏,游戏的剧情非常特别,玩家将帮助主人公切斯特,前往神秘森林,解开疾病的谜题,并找出神秘岛屿的秘密。详情>>

阅读: 0
日期: 2019-09-06
EndlessMirage英文版

《EndlessMirage》是一款平台冒险类游戏,这款游戏有着与《iwanna》系列小游戏一样的画风,不过游戏在难度上有了少许下调,并且对画面丰富度进行了充实,可以看做是一款“超清详情>>

阅读: 0
日期: 2019-09-06
Energia英文版

游戏简介《Energia》是由MarkSowders推出的一款轻松休闲的策略游戏,玩家在游戏中将创建和管理一个能源网络。每个级别提供了一个有趣的新旋转的核心力学,让你用你自己的方式鼓详情>>

阅读: 0
日期: 2019-09-06
EndlessSpace2中文版

《EndlessSpace2》是太空题材4X策略大作《EndlessSpace》的续作。游戏中,玩家将来到宇宙多文明太空殖民时代,选择8个不同的派系,每个派系都有自己的故事和特色,玩家需要发展科技详情>>

阅读: 0
日期: 2019-09-06
Engolasters英文版

《Engolasters》是一个短暂而奇怪的点击冒险游戏。你是一个外星人狂热者,一直在寻找外星人的踪迹,甚至从美丽的巴塞罗那城市来到了Engolasters这个寒冷、荒凉的地方,你的儿子和详情>>

阅读: 0
日期: 2019-09-06
Enoch:地下世界英文版

《Enoch:地下世界(Enoch:Underground)》是一款冒险风格的角色扮演型游戏,带有roguelike动作元素,该作的场景设定在一个很久以前就被摧毁的古老城市内,而玩家则会控制这座城市为数详情>>

阅读: 0
日期: 2019-09-06
Enoch:地下世界破解版

《Enoch:地下世界(Enoch:Underground)》是一款冒险类的角色扮演游戏,玩家们将会控制一个被唤醒的人——在城市中幸存的少数人之一,在这个暗黑有危险的环境下进行不断地详情>>

阅读: 0
日期: 2019-09-06
正在配置microsoft office enterprise 2007

我的word2007安装以后,每次都打开Word2007时都会提示:“正在配置microsoft office enterprise 2007”,弹出Office安装配置进度向导。即便在安装时,选择安装所有功能组件,在每次打详情>>

阅读: 5
日期: 2019-06-18
The End of LifeThe End of WorldThe number of

当心爱的女生不见了,你是不是走到了世界的尽头?在世界的尽头手游里,让我们一同努力找寻背后的真相。想知道游戏怎么通关吗?那就一起来看 详情>>

阅读: 20
日期: 2019-04-28
雨中冒险2工程师Engineer解锁方法介绍

雨中冒险2丰富的角色和道具系统让游玩过程非常的有趣,其中工程师是一个很有趣的职业,很多玩家都想知道这个职业怎么解锁,下面Game234游戏门户小编能为大家带来方详情>>

阅读: 4
日期: 2019-04-08
 Java Runtime Environment v8.0.1310.11 下载

游戏类型:系统辅助文件大小:62.6M软件语言:英文运营:软件授权:免费版应用平台:WinXP/Win2003/Win7/Win8/win10/安全认证: JavaRuntimeE详情>>

阅读: 9
日期: 2019-04-03
Java SE Runtime Environment 7.0.210.0 Java7运行库游戏辅助下载

中文名称:发布日期:2013-12-17更新日期:--文件大小:57.0M游戏语言:简体中文英文名称:游戏制作:游戏发行:上市时间:2013-12-17官方网址:运行系统:XP详情>>

阅读: 8
日期: 2019-03-29
Engravings装备出处信息插件

游戏类型:物品类插件文件大小:518KB软件语言:简体中文运营:软件授权:免费版应用平台:WIN9X/2000/XP/VISTA安全认证:Engravings插件说明:  Engravings详情>>

阅读: 7
日期: 2019-03-14
Apex英雄EngineError错误提示解决方法

  Apex英雄EngineError错误提示详情>>

阅读: 3
日期: 2019-02-27
「灵能百分百」外传「REIGEN」单行本推出

ONE的漫画「REIGEN~灵级值MAX131的男人~」在2月19日发售。「REIGEN~灵级值MAX131的男人~」详情>>

阅读: 13
日期: 2019-02-20
吃鸡类游戏《Apex Lengends》火爆上线,网易UU助力畅玩

在2014年3月份,由RespawnEntertainment工作室制作并由美国艺电公司发行的的第一人称射击网络游戏《泰坦天降》正式与玩家见面,在广受好评之后,该游戏的续作《详情>>

阅读: 4
日期: 2019-02-14
吃鸡类游戏《Apex Lengends》火爆上线,网易UU助力畅玩嗨翻天

  在2014年3月份,由RespawnEntertainment工作室制作并由美国艺电公司发行的的第一人称射击网络游戏《泰坦天降》正式与玩家见面,在广受好评之后,该游戏的续作详情>>

阅读: 10
日期: 2019-02-14
enjoy summer holiday 天天酷跑字母O在哪里收集

7月9日0:00~7月15日23:59期间,收详情>>

阅读: 4
日期: 2019-01-21
enjoy summer holiday 天天酷跑字母收集奖励一览

天天酷跑字母收集玩法开启,目前已经不少玩家将本详情>>

阅读: 4
日期: 2019-01-21
enjoy summer holiday 酷跑字母H在哪里收集

天天酷跑字母收集活动再度来袭,本次需要玩家们收详情>>

阅读: 2
日期: 2019-01-21
绝地求生enable anti-cheat什么意思 enable anti-cheat要选吗

绝地求生enable anti-cheat到底是什么意思呢,很多玩家...如果你选择了这个选项之后出现了不兼容的问题,那么就... 详情>>

阅读: 8
日期: 2018-11-11
《无限法则》Europa encountered 报错怎么解决 Europa encountered 报错解决方法

无限法则现在虽然能玩,但是还处于测试期间,多少会有一些问题。很多玩家在下载游戏后,会出现Error Report,提示Europa encountered a 详情>>

阅读: 0
日期: 2018-10-17
精彩推荐