个人档案【转】你必知道之EF知识和涉

个人档案【转】你必知道之EF知识和涉

【转】你必须掌握的EF知识及经验

注意:以下内容如果没有特别说明,默认使用的EF6.0版本,code first模式。

推荐MiniProfiler插件

工欲善其事,必先利其器。

咱们用EF和在深要命程度增长了支出速度,不过就带动的是无数性质低下的写法和浮动不顶高速之sql。

虽咱可采用SQL Server
Profiler来监控实施之sql,不过个人认为就是麻烦,每次用打开、过滤、清除、关闭。

以这边强烈推荐一个插件MiniProfiler。实时监控页面请求对许实行之sql语句、执行时间。简单、方便、针对性强。

如图:(具体使用和介绍请走)

个人档案 1

数据准备

新建实体:Score(成绩分数表)、Student(学生说明)、Teacher(老师表)

个人档案 2

末端会于出demo代码下充斥链接

foreach循环的陷进 

1.有关延迟加载

个人档案 3

告看上图红框。为什么StudentId有价,而Studet为null?因为用code
first,需要装导航属性也virtual,才见面加载延迟加载数据。

个人档案 4

2.关于在循环中做客导航属性之老大处理(接着上面,加上virtual后会见报以下很)

“已发出开拓的同此 Command 相关联的
DataReader,必须首先以她倒闭。”

个人档案 5

化解方案:

  • 方案1、设定ConnectionString加上MultipleActiveResultSets=true,但才适用于SQL
    2005随后的本子
  • 方案2、或者先念来放置于List中

3.之上两沾单为热身,我们说之陷阱才刚刚开始!

个人档案 6

下一场我们点击打开MiniProfiler工具(不要让吓到)

个人档案 7

个人档案 8

解决方案:使用Include著连续查询(注意:需要手动导入using System.Data.Entity
不然Include只能传表名字符串)。

个人档案 9

又看MiniProfiler的督察(瞬间101久sql变成了1久,这之中的属性可想而知。)

个人档案 10

AutoMapper工具

上面我们透过Include显示的执行表的连查询显然是毋庸置疑的,但还不够。如果我们无非待查询数据的一些字段呢,上面查询所有字段岂不是大浪费内存存储空间和应用程序与数据库数据传带富。

俺们好:

个人档案 11

针对许监督及之sql:

个人档案 12

咱看到变化的sql,查询的字段少了累累。只有咱来得列出来字段的与一个StudentId,StudentId用来连续查询条件的。

是,这样的法门要命不错。可是有没产生什么更好的方案或措施也?答案是早晚的。(不然,也未会见以这边屁话了。)如果表字段非常多,我们要用的字段也颇多,导航属性为老多之时段,这样的手动映射就显示不那么好看了。那么接下我们初步介绍以AutoMapper来就投:

顾:首先得NuGet下载AutoMapper。(然后导入命名空间 using
AutoMapper; using AutoMapper.QueryableExtensions;)

个人档案 13

个人档案 14

咱俩视地方查询语句没有一个个之手动映射,而映射都是单独布置了。其中CreateMap应该是使描绘及Global.asax文件中的。(其实也尽管是分开了照部分,清晰了询问语句。细心的同桌或注意到了,这种措施尚未去了积极性Include)

个人档案 15

我们看出了变的sql和前面有多少见仁见智,但只大成了扳平长条sql,并且结果吗是不利的。(其实就是是多了同样漫漫CASE WHEN ([Extent2].[Id] IS
NOT NULL) THEN 1 END AS
[C1]。看起就长达告句子并从未呀实际意义,然而当下是AutoMapper生成的sql,同时自也表示未理解为什么和EF生成的例外)

这样做的益处?

  1. 避以循环中做客导航属性多次履sql语句。
  2. 避了查询语词被最好多的手动映射,影响代码的读书。

有关AutoMapper的其他有素材:

http://www.cnblogs.com/xishuai/p/3712361.html

http://www.cnblogs.com/xishuai/p/3700052.html

http://www.cnblogs.com/farb/p/AutoMapperContent.html

联表查询统计

要求:查询前100单学生考项目(“模拟考试”、“正式考试”)、考试次数、语文平均分、学生姓名,且考试次数超过等于3赖。(按考试项目分类统计)

代码如下:

个人档案 16

看来这般的代码,我第一反响是灾难性了。又于循环执行sql了。监控如下:

个人档案 17

事实上,我们只是需要有些改变就将101长达sql变成1长达,如下:

个人档案 18

马上变1条。

个人档案 19

俺们开拓查看详细的sql语句

个人档案 20

发现就仅仅只是查询结果集合而已,其中的依考试类别来统计是先后将到具备数据后以算的(而无是以数据库内计算,然后直接返回结果),这样平等是荒废了数据库查询数据传。

至于连接查询分组统计我们得以使用SelectMany,如下:

个人档案 21

监控sql如下:(是免是简单多了吗?)

个人档案 22

关于SelectMany资料:

http://www.cnblogs.com/lifepoem/archive/2011/11/18/2253579.html

http://www.cnblogs.com/heyuquan/p/Linq-to-Objects.html

性提升的AsNonUnicode

个人档案 23

督察到的sql

个人档案 24

我们看EF正常情况变化的sql会于前面带齐“N”,如果我们抬高DbFunctions.AsNonUnicode生成的sql是无“N”的,当你发觉带来达“N”的sql比没带来“N”的
sql查询速度放缓很多底上那么就是亮该怎么处置。

(以前用oracle的时候带不带“N”查询效率差别特别扎眼,今天之所以sql
server测试并不曾发觉什么区别个人档案 25。还有我意识EF6会根据数据库被凡是nvarchar的时才会生成带“N”的sql,oracle数据库没测试,有趣味的校友可以测试下)

特性提升的AsNoTracking

个人档案 26

咱看变化的sql

个人档案 27

sql是生成的等同型一样,但是实施时间也是4.8倍。原因仅仅只是第一长EF语词多加了一个AsNoTracking。

注意:

  • AsNoTracking干啊的吗?无跟踪查询而已,也就是说查询出来的对象不克直接开修改。所以,我们于召开多少集合查询显示,而同时休待对聚集修改并创新到数据库的时,一定毫无遗忘加上AsNoTracking。
  • 假定查询过程做了select映射就不需要加AsNoTracking。如:db.Students.Where(t=>t.Name.Contains(“张三”)).select(t=>new
    (t.Name,t.Age)).ToList();

基本上字段组合排序(字符串)

渴求:查询名字里含有“张三”的学员,先以名排序,再依年龄排序。

个人档案 28

个人档案 29

哟,不对啊。按名排序为年龄排序覆盖了。我们该为此ThenBy来组合排序。

个人档案 30

个人档案 31

不错不错,正是我们怀念使的效益。如果您不思就此ThenBy,且还是升序的语,我们啊可:

个人档案 32

个人档案 33

转的sql是相同的。与OrderBy、ThenBy对应之降序有OrderByDescending、ThenByDescending。

好像好像挺完善了。其实不然,我们大部分景象排序是动态的。比如,我们见面越加前端页面不同之操作要求不同字段的两样排序。那我们后台应该怎么开啊?

个人档案 34

本来,这样好是没问题之,只要您肯。可以这么多或者的论断出无产生发特别SB?是的,我们本有再度好的化解方案。要是OrderBy可以一直传字符串???

解决方案:

  1. guget下载System.Linq.Dynamic 
  2. 导入System.Linq.Dynamic命名空间
  3. 编排OrderBy的恢宏方法

个人档案 35

下一场上面又增长而臭的代码可以形容成:

个人档案 36

咱看下转移的sql:

个人档案 37

暨咱们怀念如果的力量完全符合,是免是感到美美哒!!

【注意】:流传的排序字段后面要加排序关键字
asc或desc

lamdba条件构成

要求:根据不同情形询问,可能情况

  1. 查询name=“张三” 的享有学员
  2. 查询name=“张三” 或者 age=18底具备学员

落实代码:

个人档案 38

举凡匪是味及了平等的荤个人档案 39。下面我们来活组装Lamdba条件。

釜底抽薪方案:

个人档案 40个人档案 41

顿时段代码我啊是从网上偷的,具体链接找不顶了。

然后我们的代码可以描绘成:

个人档案 42

来没有来得意美哒一点个人档案 43。然后我们看看生成的sql是否是:

个人档案 44

EF的预热

http://www.cnblogs.com/dudu/p/entity-framework-warm-up.html

count(*)被您用异常了呢(Any的用法)

渴求:查询是否存在名字呢“张三”的生。(你的代码会怎样写吗?)

个人档案 45

先是种植?第二种?第三种?呵呵,我原先就是是用的首先种植,然后有人说“你count被您用很了”,后来自己眷恋了纪念了怎么就给自己之所以生了呢?直到对比了这三个告知句的性质后自己明白了。

个人档案 46

属性的异竟有三百基本上倍增,count确实于自己为此好了。(我思,不止于自己一个人数所以老了吧。)

咱们看出上面的Any干嘛的?官方解释是:

个人档案 47

自数读者中文说,一直无法了解。甚至早有人为提出了同样的问题《实在看无懂MSDN关于
Any
的说》

从而我个人理解吧是“确定集合中是否发生素满足某平规范”。我们来看望any其他用法:

渴求:查询教了“张三”或“李四”的教工

兑现代码:

个人档案 48

简单种植方法,以前我会习惯写第一种。当然我们看看那个成了之sql和实行效率之后,看法改变了。

个人档案 49

频率的差竟有近六倍

咱俩重对照下count:

个人档案 50

个人档案 51

得出奇怪的定论:

  1. 于导航属性之中用count和用any性能分不慌,反而FirstOrDefault()
    != null的方式性能最好差。
  2. 在一直性判断其中any和FirstOrDefault() !=
    null性能分不要命,count性能使差的多。
  3. 故此,不管是直接性还是导航属性我们还用any来判定是否有是不过稳妥的。

透明标识符

假定由于各种缘由我们用写下面这样逻辑的说话

个人档案 52

咱得以形容成这样更好

个人档案 53

看生成的sql就知道了

个人档案 54

仲种植方式变的sql要彻底得差不多,性能为重新好。

EntityFramework.Extended

此推荐下插件EntityFramework.Extended,看了生,很对。

无限可怜之独到之处就是是足以一直批量改、删除,不用像EF默认的得事先做询问操作。

关于官方EF为什么没有供这么的支持即无知底了。不过使用EntityFramework.Extended需要专注以下几点:

  1. 只支持sql server
  2. 批量修改、删除时无可知兑现工作(也便是生了特别不克回滚)
  3. 没有联级删除
  4. 不能同EF一起SaveChanges
    (详见)

http://www.cnblogs.com/GuZhenYin/p/5482288.html

当斯正个问题EntityFramework.Extended并无是说非克回滚,感谢@GuZhenYin园友的指正(原谅自己之前没动手测试)。

在意:需要NuGet下载EntityFramework.Extended,
并导入命名空间: using
EntityFramework.Extensions ;

测试代码如下:(如果注释掉手抛大代码是足以直接更新到数据库的)

using (var ctxTransaction = db.Database.BeginTransaction())
{
    try
    {
        db.Teachers.Where(t => true).Update(t => new Teacher { Age = "1" });

        throw new Exception("手动抛出异常");

        ctxTransaction.Commit();//提交事务
    }
    catch (Exception)
    {
        ctxTransaction.Rollback();//回滚事务
    }
}

自打定义IQueryable扩展方法

 最后整理下由定义之IQueryable的扩大。

 个人档案 55

个人档案 56

 

补充1:

First和Single的区别:前者是TOP(1)后者是TOP(2),后者如果查询到了2条数据则抛出异常。所以在必要的时候使用Single也不会比First慢多少。

补充2: 

一度打包nuget提供直接装 Install-Package
Talk.Linq.Extensions 或nuget搜索 Talk.Linq.Extensions 

https://github.com/zhaopeiym/Talk/wiki/Talk.Linq.Extensions_demo

 

结束:

源码下载:http://pan.baidu.com/s/1o8MYozw

本文为协同到《C#基础知识巩固系列》

迎热心园友补充!

admin

网站地图xml地图