我们利用变量替换值改造后结果生成的SQL语句与上述截然不同,这里同样是声明了长度的变量,你发现没该变量居然和我们声明的变量长度是一致的,有点神奇,如此这样通过变量替换值得方式来达到SQL查询计划重用的目的,说到这里,我们是不是应该回答一下为什么会有这样的情况发生呢。很多东西当你一直没用到时就觉得不会用到压根不用学,其实不然,比如这样,其本质到底是怎样的呢,其实是因为前面我已经讲过【闭包】的原因。
lambda表达式对我们声明的变量进行了捕获然后延长了其生命周期,也就是说将变量类似变成类中一个字段了,类似如下:
[CompilerGenerated] ExampleClass1 { public int Length; } [CompilerGenerated] ExampleClass2 { public int Length; }
自动编译生成两个类同时存在两个对于长度的字段。接下来当我们利用变量进行查询就演变了如下这样:
var ef = new EFCoreContext(); var blogs = ef.Blogs; var length = 1; var example1 = new ExampleClass1() { Length = length }; var skipTakeWithVariable1 = blogs .OrderBy(b => b.Id).Where(d => d.Name.Length > example1.Length).ToList(); length = 10; var example2 = new ExampleClass2() { Length = length }; var skipTakeWithVariable2 = blogs .OrderBy(b => b.Id).Where(d => d.Name.Length > example2.Length).ToList();
这样就很明了了为什么通过变量达到查询计划重用的目的。
总结关于EntityFramework Core虽然目前设计的性能非常好,但是有些东西等我们去用时还得多加验证,看其背后的本质是怎样的,才能不会心生疑窦,到底该怎样用,如何用,心中要有定数才是,一点一滴的细小优化不注意最终将导致大意失荆州。接下来博主会在三个方向不定时更新博客,第一个是SQL Server性能优化系列,第二个是ASP.NET Core MVC/WebAPi,第三个则是EntityFramework Core原理解析,敬请期待。