EF6学习笔记三十:性能优化——预编译视图
要专业系统地学习EF推荐《你必须掌握的Entity Framework 6.x与Core 2.0》。这本书作者(汪鹏,Jeffcky)的博客:https://www.cnblogs.com/CreateMyself/
来到性能优化这里了。这里首先引用作者的一句话:EF的性能问题一直是.NET程序员热聊的话题,实际情况不是性能差,而是需要我们掌握如何规避陷阱以及影响性能的坑。
本次的学习疑点有很多
通常情况下,当首次使用EF时,查询数据的过程非常漫长,因为它必须生成用于计算要运行的查询视图。
解决方法有两种,第一,采用第三方库;第二,使用EF提供的API
既然有提供API那我就没去弄第三方库了,更多的解决方案请参考书上的内容。
在EF6.2.x中可以为EF加上配置,EF6.1.X中则不一样,下面是EF6.2.x中的写法
public class EFConfiguration: DbConfiguration { public EFConfiguration() { SetModelStore(new DefaultDbModelStore(Directory.GetCurrentDirectory())); } }
当首次调用Enable-migrations命令后,会在VS编译器所在目录生成模型edmx缓存,在项目中的bin/bebug里面也会生成一个这个的文件
当你执行enable-migrations遇到下面这样的情况后请以管理员的身份运行VS再执行enable-migrations
vs安装目录
项目文件目录
这里就不得不去看一下edmx是什么东西。因为即使这样做了之后我也不知道优化在哪里?难道edmx就是预编译视图?不是,作者并没有这么说
edmx是EF的核心文件,在我们使用Dbfirst模式的时候就会生成edmx文件,一个XML文件,里面的内容来看一下
复习一下EF的架构
Conceptual Schema Define Layer (CSDL) 概念架构定义层 对象的世界(开发人员面向这一层)
Mapping Schema Layer (MSL) 映射架构层 映射
Storage Schema Define Layer (SSDL) 存储架构定义层 数据的世界(这一层专门和数据库打交道)
那么edmx就是对这几层具体的配置,不知道具体的情况我就不过多的瞎说了
来一个笨的办法,将里面的单词都翻译一样,读个似懂非懂也好
ConceptualModels 概念模型
Mappings 映射
StorageModels 存储模型
看了一下,虽说edmx是个XML文件,但是他其实可以可视化读取的 ,就像图片可以用图片查看器打开一样
我们把刚刚生成的edmx文件复制到项目中来看看,它对应的就是这个!是不是很熟悉
在我刚刚开始接触EF的时候我用到以前根本就不知道的Dbfirst这些概念也弄出过这个,可视化的去进行建模
可以看到还有一个Model.tt的文件,这个关于到T4模块,对这一块我比较空白,大家可以参考网上的其他资料
我现在要做的就是用一下Dbfirst
项目右击-->添加-->新建项-->实体数据模型
现在就会在项目中创建edmx文件和.tt文件
来看一下和刚刚生成的edmx文件有何区别
conceptialModels
Mappings
StorageModels
Designer
可以看到配置差不多,但是配置属性值大都不一样,主要是他们面向的对象不一样,一个是面向数据库的,一个是面向EF的
最后这个Designer我不理解,就当是学单词了
在Designer配置中有个属性CodeGenerationStartegy,一个是“None”,一个是“无”
那么后一种是汉化投入较多的原因吗?
我昨天就发现一个问题,就是我用DbFrist 生成了edmx文件,然后我来打印EF上下文提供的数据库日志,发现是中文的
using (EFDbContext ctx = new EFDbContext()) { ctx.Database.Log = msg => Console.WriteLine($"张四海-------------{msg}"); var stu = ctx.Students.FirstOrDefault(); Console.WriteLine(JsonConvert.SerializeObject(stu)); }
那么我就猜想是DbFirst中汉化投入较多。因为它是可视化建模的,比如说我们安装一个软件会经常弄汉化包
但是为什么Codefirst里面又都是英文呢?应该就是本身可视化操作的东西就会对汉化有比较大的需求,而codefirst,全部是通过写代码来的,那这个需求就没了。
现在来说说问题
在用Dbfirst的时候,肯定是对edmx这个文件非常熟悉,因为你可能会经常对它改动,因为所有的这些配置都是在这个文件中。
CodeFirst是较Dbfirs后出来的。那么我学了那么长时间的EF,怎么觉得edmx(别人一说是EF的核心文件)一点存在感都没有呢?
那是现在通过fluent API 或者DataAnnotations的方式,这个有形的edmx文件已经升华成了代码。我就是这样理解的。
那么是不是edmx是不是就是作者说的预编译视图呢?
既然已经升华成了代码,那就应该不需要edmx文件才对啊,怎么又生成了一个呢?
继续猜想,回到作者开头说的一句话:当首次使用EF时,查询数据的过程非常漫长,因为它必须生成用于计算要运行的查询视图。
那么它是不是在运行时还是会根据代码来生成一个内存化的edmx?虽然他没有生成一个可见的edmx,但是在内存中,关于EF的那些配置、映射还是会构造、销毁以此来完成
edmx那些配置的内容?
所以现在手动生成了edmx文件后,它就不会再 做这些工作了?
我的推理就到这里了,我只能去这样想了。那么我得到的结果就是:edmx文件就是作者说的预编译视图。
那么按照作者提供的方式,它生成的edmx文件只需要在放在项目文件目录中就行了呀,为什么还在Vs的安装目录下也会生成一个这样的文件?
行吧,我觉得这里我有点无能为力了。最后来看一下我们可以通过IO和EF提供的EdmxWriter对象直接将上下文写入到一个XML文件,就是一个edmx文件
using (EFDbContext ctx = new EFDbContext()) { XmlWriterSettings settings = new XmlWriterSettings(); settings.Indent = true; using (XmlWriter writer = XmlWriter.Create(@"d:\Model.edmx",settings)) { EdmxWriter.WriteEdmx(ctx,writer); } }