EntityFramework Core 2.0 Explicitly Compiled Query(显式编译查询)

前言

EntityFramework Core 2.0引入了显式编译查询,在查询数据时预先编译好LINQ查询便于在请求数据时能够立即响应。显式编译查询提供了高可用场景,通过使用显式编译的查询可以提高查询性能。EF Core已经使用查询表达式的散列来表示自动编译和缓存查询,当我们的代码需要重用以前执行的查询时,EF Core将使用哈希查找并从缓存中返回已编译的查询。我们更希望直接使用编译查询绕过散列计算和高速缓存查找。

EntityFramework Core 2.0显式编译查询

比如我们要从博客实体中通过主键查询博客同时饥饿加载发表文章的集合列表,如下:

            var id = 1;using (var context = new EFCoreDbContext()){var blog = context.Blogs.AsNoTracking().Include(c => c.Posts).Where(c => c.Id == id).FirstOrDefault();}

当进行上述查询时,此时要经过编译翻译阶段最终返回实际结果,比如在Web网站上这样的请求很频繁,此时将严重影响响应速度导致页面加载数据过慢。从Web程序应用角度来看我们大可利用ASP.NET Core中的响应式缓存,在实际应用中我们会将查询封装为方法来使用,我们无法优化结果和查询方式,但是我们能够通过编译查询来提前保存好数据以达到缓存的效果。通过EF静态类中的扩展方法CompileQuery来实现。如下:

        static async Task<Blog> GetBlogAsync(EFCoreDbContext context, int id){Func<EFCoreDbContext, int, Task<Blog>> blog = EF.CompileAsyncQuery((EFCoreDbContext context, int Id) =>context.Blogs.Include(c => c.Posts).Where(c => c.Id == Id).FirstOrDefault());return await blog(context, id);}

常规查询和显式编译查询性能比较

接下来我们测试常规查询和使用显式编译查询的性能,我们利用EF Core提供的内存数据库来测试避免使用SQL Server数据库,利用SQL Server数据库很难去比较二者性能问题,因为数据库会进行查询计划优化和缓存,利用内存数据库只知道当前执行的查询不会进行任何优化, 首先我们下载EF Core内存数据库。额外再说明一点内存数据库在进行单元测试时很有意义。

接下来我们首先测试常规查询,我们预先在内存数据库中创建50条记录,然后查询十万次数据,这样来看每一次查询都会再次重新编译。

        public static void Main(string[] args){var options = new DbContextOptionsBuilder<EFCoreDbContext>().UseInMemoryDatabase(Guid.NewGuid().ToString()).Options;var context = new EFCoreDbContext(options);var stopWatch = new Stopwatch();FillBlogs(context);stopWatch.Start();for (var i = 0; i < 1000000; i++){GetUnCompileQueryBlog(context);}stopWatch.Stop();Console.Write("Compiling time:");Console.WriteLine(stopWatch.Elapsed);Console.ReadKey();}static void FillBlogs(EFCoreDbContext context){for (var i = 0; i < 50; i++){context.Blogs.Add(new Blog{Name = "Jeffcky",CreatedTime = DateTime.Now,Url = "http://www.cnblogs/com/CreateMyself",ModifiedTime = DateTime.Now,Posts = new List<Post>(){new Post(){CommentCount = i, CreatedTime = DateTime.Now,ModifiedTime = DateTime.Now, Name = "EF Core"}}});}context.SaveChanges(true);}static Blog GetUnCompileQueryBlog(EFCoreDbContext context){return context.Blogs.Include(c => c.Posts).OrderBy(o => o.Id).FirstOrDefault();}

我们看到上述利用常规查询总耗时27秒,接下来我们再来看看显式编译查询耗时情况。

private static Func<EFCoreDbContext, Blog> _getCompiledBlog = EF.CompileQuery((EFCoreDbContext context) =>context.Blogs.Include(c => c.Posts).OrderBy(o => o.Id).FirstOrDefault());
            var options = new DbContextOptionsBuilder<EFCoreDbContext>().UseInMemoryDatabase(Guid.NewGuid().ToString()).Options;var context = new EFCoreDbContext(options);var stopWatch = new Stopwatch();FillBlogs(context);stopWatch.Start();for (var i = 0; i < 100000; i++){GetCompileQueryBlog(context);}stopWatch.Stop();Console.Write("Compiling time:");Console.WriteLine(stopWatch.Elapsed);Console.ReadKey();

如上通过显式编译查询耗时16秒,那么是不是就说明显式编译查询性能一定优于常规查询呢?显然不是这样,上述只是简单的测试方法,有可能运行多次显式编译查询性能还低于常规查询,所以上述简单的测试方法并不能看出常规查询和显式编译查询之间的性能差异,当查询基数足够大时则能通过机器明显看出二者之间的性能差异,这也就说明了为什么EntityFramework Core官方文档说明显式编译查询的高可用。但是显式编译查询还有且缺点,当我们进行如下查询呢?

        public static void Main(string[] args){var options = new DbContextOptionsBuilder<EFCoreDbContext>().UseInMemoryDatabase(Guid.NewGuid().ToString()).Options;var context = new EFCoreDbContext(options);var blogs = GetCompileQueryBlogs(context);Console.ReadKey();}static Blog[] GetCompileQueryBlogs(EFCoreDbContext context){Func<EFCoreDbContext, Blog[]> func = EF.CompileQuery((EFCoreDbContext db) =>db.Blogs.Include(c => c.Posts).OrderBy(o => o.Id).ToArray());return func(context);}}

当前EntityFramework Core 2.0.1版本对于显式编译查询还不支持返回IEnumerable<T>, IQueryable<T>的集合类型,期待未来能够有所支持。

总结缺陷

显式编译查询提供高可用场景,但是仍然存在其缺陷,期待未来能有更多支持,希望给阅读的您一点帮助。精简的内容,简单的讲解,希望对阅读的您有所帮助,我们明天再会。

转载于:https://www.cnblogs.com/CreateMyself/p/8519512.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/539212.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

.net 导出excel_Qt编写的项目作品18-数据导出到Excel及Pdf和打印数据

一、功能特点原创导出数据机制&#xff0c;不依赖任何office组件或者操作系统等第三方库&#xff0c;尤其是支持嵌入式linux。10万行数据9个字段只需要2秒钟完成。只需要四个步骤即可开始急速导出大量数据到Excel。同时提供直接写入数据接口和多线程写入数据接口&#xff0c;不…

图像增强_Keras 常用的图像增强方式

欢迎关注 “小白玩转Python”&#xff0c;发现更多 “有趣”在使用神经网络和深度学习模型时&#xff0c;需要进行数据准备。对于更复杂的物体识别任务&#xff0c;也越来越需要增加数据量。数据增加意味着增加数据量。换句话说&#xff0c;拥有更大的数据集意味着更健壮的模型…

Facebook产品经理的三年叙事与协作思考

产品经理和研发工程师的关系经常被大家调侃&#xff0c;可偏偏就有同时受到研发和设计都喜欢的“别人家的产品经理”&#xff0c;沟通协调、对接需求、项目把控面面俱到还有好人缘。有没有人天生就是产品经理&#xff1f;产品经理的工作就是写需求写需求和写需求么&#xff1f;…

sis新地址_坚若磐石不掉速,老平台升级新选择,入手昱联Asint 500G SSD

我是文章的原作者&#xff0c;文章首发于&#xff1a;什么值得买爱折腾的老狐狸​zhiyou.smzdm.com首发文章链接&#xff1a;坚若磐石不掉速&#xff0c;老平台升级新选择&#xff0c;入手昱联Asint 500G SSD _值客原创_什么值得买​post.smzdm.com虽然说&#xff0c;现在越来越…

进度条设置_为你的练习设置进度条

在我们的日常练习中&#xff0c;遇到最多的一个问题就是不知道自己练得怎么样了&#xff1f;还需不需要继续&#xff0c;或者调整练习方法。这种问题大多出现在自学吉他的学生当中&#xff0c;因为得不到老师的反馈&#xff0c;自己练得对不对&#xff0c;够不够&#xff0c;都…

Python之路(第二篇):Python基本数据类型字符串(一)

一、基础1、编码 UTF-8:中文占3个字节 GBK&#xff1a;中文占2个字节 Unicode、UTF-8、GBK三者关系 ascii码是只能表示英文字符&#xff0c;用8个字节表示英文&#xff0c;unicode是统一码&#xff0c;世界通用码&#xff0c;规定采用2个字节对世界各地不同文字进行编码&#x…

python ftp下载文件_文件上传下载Python

点击上方蓝字关注我&#xff01;图片来源 pexels.com简单实现文件上传、下载1 Server端 # -*- coding: utf-8 -*-import jsonimport os__author__ sange# Time : 2020/8/17 下午5:26# Author : sange# File : tcpserver_socket.py# Software: PyCharmimport socketserv…

react json转换_Typescript + React 新手篇

极链科技前端工程师茅丹丹前言 TS是什么Type Type (标准JS)。TS的官方网站&#xff1a;Type is a typed superset of Java that compiles to plain Java。Type是一个编译到纯JS的有类型定义的JS超集。 TS优点 TS 最大的优势是它提供了强大的静态分析能力&#xff0c;结合 TSL…

android listview 滑动条显示_第七十六回:Android中UI控件之RecyclerView基础

各位看官们&#xff0c;大家好&#xff0c;上一回中咱们说的是Android中UI控件之ListView优化的例子&#xff0c;这一回咱们说的例子是UI控件之RecyclerView。闲话休提&#xff0c;言归正转。让我们一起Talk Android吧&#xff01;看官们&#xff0c;我们在前面章回中介绍了Lis…

Hive的数据模型-外部表

概述 包含External 的表叫外部表 删除外部表只删除metastore的元数据&#xff0c;不删除hdfs中的表数据 外部表 只有一个过程&#xff0c;加载数据和创建表同时完成&#xff0c;并不会移动到数据仓库目录中&#xff0c;只是与外部数据建立一个链接。当删除一个 外部表 时&…

centos默认安装mysql_centos6.x默认安装mysql5.7

1. yum 安装 mysql5.7 yum 源yum localinstall mysql57-community-release-el6-8.noarch.rpm2. 查看是否成功安装MySQL Yum Repositoryyum repolist enabled|grep ""mysql.*-community.*3. 安装mysqlyum install mysql-community-server4.开启数据库服务service mys…

Hive的数据模型-分区表

需求 select * from t1 where xxxx; 这是全表扫描的。实际应用中&#xff0c;有时候不一定需要全表扫描。 比如电信的日志文件&#xff0c;一个表里存了从去年到现在的日志文件&#xff0c;那是很多很大的&#xff0c;实际需求要查今天的&#xff0c;如果用上面的sql&#xf…

arduino 停止程序_建立Arduino机器人,第五部分:障碍规避

欢迎阅读教程系列的第五篇文章&#xff0c;其中我正在构建一个基于遥控Arduino的车辆机器人。这是我到目前为止发表的文章列表&#xff1a;第一部分&#xff1a;硬件组件第二部分&#xff1a;Arduino编程第三部分&#xff1a;组装机器人第四部分&#xff1a;A(不是那样)基本机器…

Yarn简单介绍及内存配置

在这篇博客中&#xff0c;主要介绍了Yarn对MRv1的改进&#xff0c;以及Yarn简单的内存配置和Yarn的资源抽象container。我么知道MRv1存在的主要问题是&#xff1a;在运行时&#xff0c;JobTracker既负责资源管理又负责任务调度&#xff0c;这导致了它的扩展性、资源利用率低等问…

mysql计算时间函数_mysql时间计算函数

当前一个业务需求&#xff0c;需要查找创建在三天以前的数据&#xff0c;表中是存了一个创建时间的&#xff1b;这个需求看起来很简单&#xff0c;直接全部查找出来然后用代码根据时间筛选一下就可以了。但这只是适用于数据量不大的情况下&#xff0c;如果数据量大&#xff0c;…

html上传文件_.NET基于WebUploader大文件分片上传、断网续传、秒传

(给DotNet加星标&#xff0c;提升.Net技能)转自&#xff1a;学习中的苦与乐cnblogs.com/xiongze520/p/10412693.html现在的项目开发基本上都用到了上传文件功能&#xff0c;或图片&#xff0c;或文档&#xff0c;或视频。我们常用的常规上传已经能够满足当前要求了&#xff0c;…

Hadoop运行任务时一直卡在: INFO mapreduce.Job: Running job

原文链接&#xff1a;http://blog.csdn.net/dai451954706/article/details/50464036 ----------------------------------------------------------------------------------------------------- 今天&#xff0c;一大清早同事就让我帮他解决Hive的问题&#xff1a;他在Hive中…

git切换用户密码_Git 最基本的命令

本人比较懒&#xff0c;不是很爱学习新东西&#xff0c;之前用Git一直在用GUI SourceTree&#xff0c;今天因为用到Cloud IDEGitHub才迫不得已用一下Git的命令行&#xff0c;如果你是Git的新手&#xff0c;也分享给你最基本的命令。新建一个Git版本库把一个本地文件夹变成一个G…

动态分区装载数据

不开启 一个个分区导入&#xff0c;分区需要做到一对一。 hive (zmgdb)> insert overwrite table p_t3 partition (cityningbo) > select name,post,address from p_t1 where cityningbo; 会启动mapreduce进行导入&#xff0c;mr卡在kill job_xxxx&#…

AI造福设计师:搭配色板这种苦差事交给GAN就好啦(教程)

本文来自AI新媒体量子位&#xff08;QbitAI&#xff09;设计师要开工&#xff0c;总是离不开配色方案&#xff0c;也就是色板。 不过&#xff0c;做色板可不是个简单的活&#xff0c;色板生成器Colormind的作者Jack Qiao&#xff08;名字来自Product Hunt&#xff0c;我们下面叫…