今天,我将向您展示这些EF Core中一个很酷的功能,通过使用显式编译的查询,提高查询性能。

不过在介绍具体内容之前,需要说明一点,EF Core已经对表达式的编译使用了缓存;当您的代码需要重用以前执行的查询时,EF Core将使用哈希查找并从缓存中返回已编译的查询。

关于这一点,您可以查阅github上面的代码QueryCompiler.cs

不过,您可能希望直接对查询进行编译,跳过哈希的计算和缓存查找。我们可以通过在EF静态类中下面两个方法来实现:

这些方法允许您定义一个已编译的查询,然后通过调用一个委托调用它。

如果您对表达式的哈希计算感兴趣,可以看一看它的实现,非常复杂,ExpressionEqualityComparer.cs

为了避免因为数据库查询产生测试结果的差异,我们这里使用内存数据库,它开销更小,同时也可以避免数据库优化执行计划以及缓存所带来的问题。

实体定义以前数据库DbContext

定义实体

在这我们定义一个Category实体类型,非常简单,只有两个属性。

    public class Category
{
public Guid Id { get; set; }
public string Name { get; set; }
}

数据库DbContext

FillCategories方法中,将内存数据库中增加三条记录。

    public class TestDbContext : DbContext
{
public TestDbContext(DbContextOptions<TestDbContext> options) : base(options)
{
} public DbSet<Category> Categories { get; set; } public void FillCategories()
{
var foodCategory = new Category {
Id = Guid.NewGuid(),
Name = "Food"
}; Categories.AddRange(foodCategory, new Category {
Id = Guid.NewGuid(),
Name = "Drinks"
}, new Category {
Id = Guid.NewGuid(),
Name = "Clothing"
}, new Category {
Id = Guid.NewGuid(),
Name = "Electronis"
}); SaveChanges(true);
}
}

测试代码

    public class CompileQueryTest
{
private Func<TestDbContext, Guid, Category> _getCategory =
EF.CompileQuery((TestDbContext context, Guid id) => context.Categories.FirstOrDefault(c => c.Id == id)); private readonly TestDbContext _dbContext; public CompileQueryTest()
{
var options = new DbContextOptionsBuilder<TestDbContext>().UseInMemoryDatabase(Guid.NewGuid().ToString()).Options;
var context = new TestDbContext(options); context.FillCategories(); _dbContext = context;
} private readonly Guid _queryId = Guid.NewGuid(); [Benchmark]
public void CompiledQuery()
{
_ = _getCategory(_dbContext, _queryId);
} [Benchmark]
public void UnCompiledQuery()
{ _ = _dbContext.Categories.FirstOrDefault(c => c.Id == _queryId); }
}

为了更加接近测试结果,我们在构造函数中创建TestDbContext对象以及填充数据库。

测试结果

我们使用Benchmark.Net进行基准测试,测试结果如下:

Method Mean Error StdDev
CompiledQuery 10.59 us 0.0580 us 0.0543 us
UnCompiledQuery 79.55 us 0.7860 us 0.7353 us

经过编译的查询比未编译过的查询存在接近8倍的差距。如果您对这个功能感兴趣,不防自己测试一下。

EF Core 使用编译查询提高性能的更多相关文章

  1. 深入理解 EF Core:使用查询过滤器实现数据软删除

    原文:https://bit.ly/2Cy3J5f 作者:Jon P Smith 翻译:王亮 声明:我翻译技术文章不是逐句翻译的,而是根据我自己的理解来表述的.其中可能会去除一些本人实在不知道如何组织 ...

  2. EF Core 的关联查询

    0 前言 本文会列举出 EF Core 关联查询的方法: 在第一.二.三节中,介绍的是 EF Core 的基本能力,在实体中配置好关系,即可使用,且其使用方式,与编程思维吻合,是本文推荐的方式. 第四 ...

  3. EF core的原生SQL查询以及用EF core进行分页查询遇到的问题

    在用.net core进行数据库访问,需要处理一些比较复杂的查询,就不得不用原生的SQL查询了,然而EF Core 和EF6 的原生sql查询存在很大的差异. 在EF6中我们用SqlQuery和Exe ...

  4. Dapper, Ef core, Freesql 插入大量数据性能比较(一)

    需求:导入9999行数据时Dapper, Ef core, Freesql 谁的性能更优,是如何执行的,级联增加谁性能更佳. 确认方法:sql server 的 sys.dm_exec_query_s ...

  5. Dapper, Ef core, Freesql 插入大量数据性能比较(二)

    在上一篇文章中,我们比较出单表插入9999行数据,Dapper > EfCore > Freesql.在本文中,我们来看看级联插入 构建9999行数据 List<Entity> ...

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

    前言 EntityFramework Core 2.0引入了显式编译查询,在查询数据时预先编译好LINQ查询便于在请求数据时能够立即响应.显式编译查询提供了高可用场景,通过使用显式编译的查询可以提高查 ...

  7. Cookies 初识 Dotnetspider EF 6.x、EF Core实现dynamic动态查询和EF Core注入多个上下文实例池你知道有什么问题? EntityFramework Core 运行dotnet ef命令迁移背后本质是什么?(EF Core迁移原理)

    Cookies   1.创建HttpCookies Cookie=new HttpCookies("CookieName");2.添加内容Cookie.Values.Add(&qu ...

  8. EF 6.x、EF Core实现dynamic动态查询和EF Core实现多个上下文实例池你了解多少?

    前言 很长一段时间没有写博客了,今天补上一篇吧,偶尔发现不太愿意写博客了,太耗费时间,不过还是在坚持当中,毕竟或许写出来的东西能帮到一些童鞋吧,接下来我们直奔主题.无论是在在EF 6.x还是EF Co ...

  9. 讨论过后而引发对EF 6.x和EF Core查询缓存的思考

    前言 最近将RabbitMQ正式封装引入到.NET Core 2.0项目当中,之前从未接触过是个高大上的东东跟着老大学习中,其中收获不少,本打算再看看RabbitMQ有时间写写,回来后和何镇汐大哥探讨 ...

随机推荐

  1. STM32W108无线射频模块通用IO接口应用实例

    STM32W108无线射频模块通用IO接口应用实例 本实例编写STM32W108的GPIO測试程序,通过控制GPIO引脚,实现对LED灯的控制. 开发环境与硬件说明 硬件:STM32W108无线开发板 ...

  2. 【Sqlserver系列】CAST和CONVERT

    1   概述 本篇文章主要讲解SqlServer中类型转换涉及的两个函数:CAST和CONVERT. 2   具体内容 2.1  CAST (1)作用:将一种数据类型的表达式转换为另一种数据类型的表达 ...

  3. 【quickhybrid】架构一个Hybrid框架

    前言 虽然说本系列中架构篇是第一章,但实际过程中是在慢慢演化的第二版中才有这个概念, 经过不断的迭代,演化才逐步稳定 明确目标 首先明确需要做成一个什么样的框架? 大致就是: 一套API规范(统一An ...

  4. 自学WPF之Binding(二)

    没有Source的Binding,使用ContentText作为Binding源: 上一篇是把CLR类型对象当作指定为Binding的Source,两种方法:一是把对象赋值给Binding.Sourc ...

  5. [转载]ArchLinux 添加 archlinuxcn 源 密钥错误

    http://www.jianshu.com/p/8ed688b0a096 杜龙少 正在检查密钥环里的密钥 [######################] 100% 正在下载所需的密钥...... ...

  6. 商城项目整理(三)JDBC增删改查

    商品表的增加,修改,删除,订单表的增加,确认,用户表的查看,日志表的增加,查看 商品表建表语句: create table TEST.GOODS_TABLE ( gid NUMBER not null ...

  7. Python的HTTP服务实例

    1.前言 今天需要实现一个Pyhton的http服务,与Web的JS进行交换. 2.实例代码 支持HEAD.GET.POST方法,将参数转换为JSON格式,返回结果以JSON字符串返回. import ...

  8. sed 命令替换字符串

    sed -i 's/13/15/g'  `grep 13 -rl  目录` -i 表示替换 -r 表示搜索子目录 -l 显示替换名

  9. bzoj 2298: [HAOI2011]problem a

    Description 一次考试共有n个人参加,第i个人说:"有ai个人分数比我高,bi个人分数比我低."问最少有几个人没有说真话(可能有相同的分数) Input 第一行一个整数n ...

  10. rtmp流媒体搭建的所需安装包

    说明:这是基于nginx rtmp控件  搭建的rtmp流媒体服务器,在此附上的是搭建所需要的安装包,具体的搭建过程看我之前的"ubuntu流媒体搭建" 链接地址:http://p ...