默认使用的EF6.0版本。默认使用的EF6.0版本。

【转】你必掌握的EF知识和涉

【转】你必须理解的EF知识及经验,ef知识更

【转】你必知道的EF知识和涉

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

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

推荐MiniProfiler插件

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

咱运用EF和于雅可怜程度增长了付出速度,不过随后带来的是过多性低下的写法和转变不绝高速之sql。

尽管咱好采取SQL Server
Profiler来监控实施之sql,不过个人认为就是麻烦,每次要开拓、过滤、清除、关闭。

当此间强烈推荐一个插件MiniProfiler。实时监察页面请求对诺尽之sql语句、执行时。简单、方便、针对性强。

使图:(具体以和介绍请动)

推荐MiniProfiler插件

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

我们用EF和以怪十分程度提高了开支速度,不过就带来的是不少性能低下的写法和转不极端高速之sql。

尽管如此咱得以行使SQL Server
Profiler来监控执行的sql,不过个人认为就是麻烦,每次要开拓、过滤、清除、关闭。

在此间强烈推荐一个插件MiniProfiler。实时监察页面请求对承诺执行之sql语句、执行时间。简单、方便、针对性强。

如图:(切切实实采用与介绍请动)

图片 1

数量准备

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

图片 2

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

数据准备

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

图片 3

背后会让出demo代码下充斥链接

foreach循环的陷进 

1.有关延迟加载

图片 4

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

图片 5

2.有关以循环中访问导航属性的坏处理(接着上面,加上virtual后会见报以下很)

“已出开拓的及这个 Command 相关联的 DataReader,必须首先将它倒闭。”

图片 6

解决方案:

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

3.以上两接触才为热身,我们说之陷阱才刚刚开始!

图片 7

然后我们点击打开MiniProfiler工具(不要吃吓到)

图片 8

图片 9

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

图片 10

重看MiniProfiler的督查(瞬间101条sql变成了1条,这中间的性可想而知。)

图片 11

foreach循环的陷进 

1.关于推迟加载

图片 12

呼吁看上图红框。为什么StudentId有价,而Studet为null?因为运用code
first,需要设置导航属性为virtual,才会加载延迟加载数据。

图片 13

2.关于在循环中走访导航属性之坏处理(接着上面,加上virtual后会报以下很)

“已起打开的以及这 Command 相关联的
DataReader,必须首先用它们倒闭。”

图片 14

缓解方案:

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

3.之上两触及只是为热身,我们说的陷阱才刚刚开始!

图片 15

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

图片 16

图片 17

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

图片 18

重复看MiniProfiler的监察(瞬间101长长的sql变成了1长条,这之中的性可想而知。)

图片 19

AutoMapper工具

方我们由此Include显示的执行表的连天查询显然是是的,但尚不够。如果我们唯有需要查询数据的一些字段呢,上面查询所有字段岂不是好浪费内存存储空间与应用程序与数据库数据传带富。

我们可以:

图片 20

本着承诺监督及之sql:

图片 21

俺们看到变化的sql,查询的字段少了不少。只有咱展示列下字段的及一个StudentId,StudentId用来连接查询条件的。

然,这样的章程要命科学。可是有没有来什么还好之方案要方式也?答案是必然的。(不然,也非会见于这边屁话了。)如果表字段非常多,我们用采用的字段也格外多,导航属性为十分多的下,这样的手动映射就亮不那么好看了。那么连下去我们开介绍下AutoMapper来成功投:

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

图片 22

图片 23

咱们看来上面查询语句没有一个个底手动映射,而映射都是单身布置了。其中CreateMap应该是要写及Global.asax文件之中的。(其实呢不怕是分开了炫耀部分,清晰了询问语句。细心的同校可能注意到了,这种方法尚不去矣积极Include)

图片 24

咱们看看了转的sql和前来多少不等,但惟独怪成了同样久sql,并且结果也是不利的。(其实就算是大抵了一样长长的CASE
WHEN ([Extent2].[Id] IS NOT NULL) THEN 1 END AS
[C1]。看起就长长的告句并没啊实际意义,然而这是AutoMapper生成的sql,同时自身呢象征未亮堂为什么跟EF生成的差)

诸如此类做的便宜?

至于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

AutoMapper工具

面我们由此Include显示的执行表的接连查询显然是无可非议的,但尚不够。如果我们唯有需要查询数据的某些字段呢,上面查询所有字段岂不是蛮浪费内存存储空间与应用程序与数据库数据传带富。

我们可以:

图片 25

本着承诺监督及之sql:

图片 26

俺们视变化的sql,查询的字段少了很多。只有咱展示列下字段的跟一个StudentId,StudentId用来连接查询条件的。

正确,这样的章程要命科学。可是有没有产生什么还好之方案要方式也?答案是必的。(不然,也非会见于这边屁话了。)如果表字段非常多,我们用采取的字段也杀多,导航属性为死多的下,这样的手动映射就亮不那么好看了。那么连下我们开介绍下AutoMapper来就投:

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

图片 27

图片 28

俺们见到上面查询语句没有一个个的手动映射,而映射都是独自布置了。其中CreateMap应该是若写及Global.asax文件里的。(其实呢就算是分手了照部分,清晰了查询语句。细心的同班也许注意到了,这种方法尚非去了主动Include)

图片 29

俺们看出了别的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破。(按考试类别分类统计)

代码如下:

图片 30

看来如此的代码,我先是感应是惨痛了。又于循环执行sql了。监控如下:

图片 31

实际上,我们仅仅待多少改变就管101长长的sql变成1长长的,如下:

图片 32

马上变1条。

图片 33

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

图片 34

意识这仅仅只是查询结果集合而已,其中的照考试类别来统计是次将到独具数据后当盘算的(而非是以数据库内计算,然后直接返回结果),这样平等是浪费了数据库查询数据传。

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

图片 35

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

图片 36

关于SelectMany资料:

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

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

联表查询统计

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

代码如下:

图片 37

探望这么的代码,我首先感应是惨不忍睹了。又在循环执行sql了。监控如下:

图片 38

实际,我们只需要多少改变就将101长条sql变成1长,如下:

图片 39

马上变1条。

图片 40

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

图片 41

发现就仅仅只是查询结果集合而已,其中的准考试项目来统计是先后将到持有数据后在计算的(而非是当数据库内计算,然后径直回到结果),这样平等是荒废了数据库查询数据传。

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

图片 42

督察sql如下:(是无是简单多了吧?)

图片 43

关于SelectMany资料:

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

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

性提升的AsNonUnicode

图片 44

监察到的sql

图片 45

我们来看EF正常状态变化的sql会在前方带上“N”,如果我们添加DbFunctions.AsNonUnicode生成的sql是从来不“N”的,当您意识带来及“N”的sql比没带“N”的
sql查询速度迟滞很多之时节那么就是懂得该怎么收拾。

(以前用oracle的当儿带非带来“N”查询效率差别特别强烈,今天就此sql
server测试并无意识什么异样图片 46。还有自己发觉EF6会根据数据库被凡nvarchar的时候才见面生成带“N”的sql,oracle数据库没测试,有趣味的校友可以测试下)

属性提升的AsNonUnicode

图片 47

监控到的sql

图片 48

咱们视EF正常状况变化的sql会以前头带及“N”,如果我们抬高DbFunctions.AsNonUnicode生成的sql是没有“N”的,当你发现带来齐“N”的sql比尚未拉动“N”的
sql查询速度缓慢很多的当儿那么即便清楚该怎么处置。

(以前之所以oracle的上带不带“N”查询效率差别特别明确,今天为此sql
server测试并没发现什么差异图片 49。还有我发觉EF6会根据数据库中凡是nvarchar的当儿才见面生成带“N”的sql,oracle数据库没测试,有趣味之同校可以测试下)

特性提升的AsNoTracking

图片 50

咱们看变化的sql

图片 51

sql是变的平等型一样,但是实行时间可是4.8倍。原因仅仅只是第一漫漫EF语句子多加了一个AsNoTracking。

注意:

  • AsNoTracking干啊的呢?无跟踪查询而已,也就是说查询出来的靶子非可知一直开修改。所以,我们在举行多少集合查询显示,而而休需针对聚集修改并更新到数据库的时节,一定不要遗忘加上AsNoTracking。
  • 万一查询过程做了select映射就无欲加AsNoTracking。如:db.Students.Where(t=>t.Name.Contains(“张三”)).select(t=>new
    (t.Name,t.Age)).ToList();

属性提升的AsNoTracking

图片 52

俺们看变化的sql

图片 53

sql是变的同样模型一样,但是实行时间可是4.8倍。原因仅仅只是第一久EF语词多加了一个AsNoTracking。

注意:

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

差不多字段组合排序(字符串)

渴求:查询名字中含“张三”的学员,先以名排序,再比如年排序。

图片 54

图片 55

哎呀,不对啊。按名排序为年龄排序覆盖了。我们相应为此ThenBy来组成排序。

图片 56

图片 57

不错不错,正是我们怀念如果的功能。如果您切莫思就此ThenBy,且还是升序的言辞,我们呢得以:

图片 58

图片 59

变化的sql是一致的。与OrderBy、ThenBy对应之降序有OrderByDescending、ThenByDescending。

类似好像特别到了。其实不然,我们大部分情形排序是动态的。比如,我们见面尤其前端页面不同的操作要求不同字段的例外排序。那我们后台应该怎么开为?

图片 60

自,这样形成是无问题之,只要你愿意。可以这样多或的判断发生没有发觉得格外SB?是的,我们当发再次好之缓解方案。要是OrderBy可以直接传字符串???

釜底抽薪方案:

图片 61

然后上面又长又可恨的代码可以描绘成:

图片 62

咱们看下转的sql:

图片 63

和我们怀念使的效应完全符合,是匪是感到美美哒!!

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

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

求:查询名字里包含“张三”的生,先随名排序,再以年排序。

图片 64

图片 65

嘿,不对啊。按名排序为年龄排序覆盖了。我们应有为此ThenBy来组成排序。

图片 66

图片 67

不错不错,正是我们怀念使之效应。如果你莫思量就此ThenBy,且都是升序的语句,我们也得:

图片 68

图片 69

变化的sql是平的。与OrderBy、ThenBy对应之降序有OrderByDescending、ThenByDescending。

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

图片 70

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

解决方案:

  1. guget下载System.Linq.Dynamic 
  2. 导入System.Linq.Dynamic命名空间
  3. 编写OrderBy的扩展方法

图片 71

然后上面又助长又丑的代码可以描绘成:

图片 72

咱俩看下转移的sql:

图片 73

跟我们想只要之意义完全符合,是休是发美美哒!!

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

lamdba条件构成

渴求:根据不同状况询问,可能情况

兑现代码:

图片 74

是匪是味到了扳平的恶臭图片 75。下面我们来灵活组装Lamdba条件。

釜底抽薪方案:

图片 76图片 77

立段代码我也是自从网上偷之,具体链接找不顶了。

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

图片 78

生没有起美美哒一点图片 79。然后我们看生成的sql是否是:

图片 80

lamdba条件做

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

  1. 查询name=“张三” 的有着学员
  2. 查询name=“张三” 或者 age=18的有学员

心想事成代码:

图片 81

凡是无是味到了一如既往的臭气图片 82。下面我们来灵活组装Lamdba条件。

釜底抽薪方案:

图片 83图片 84

立即段代码我也是打网上偷的,具体链接找不交了。

下一场我们的代码可以描绘成:

图片 85

产生没有发生得意美哒一点图片 86。然后我们省生成的sql是否是:

图片 87

EF的预热

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

EF的预热

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

count(*)被公用老了邪(Any的用法)

渴求:查询是否是名字为“张三”的学习者。(你的代码会如何写吗?)

图片 88

先是种?第二栽?第三栽?呵呵,我原先就是是采用的首先种植,然后有人说“你count被您用大了”,后来自我思了纪念了怎么就叫我因此异常了啊?直到对比了当下三独告知句之属性后自己理解了。

图片 89

特性的异竟有三百几近倍,count确实被我因此生了。(我眷恋,不止于我一个口之所以非常了咔嚓。)

俺们看看地方的Any干嘛的?官方解释是:

图片 90

自家多次读者中文说,一直无法清楚。甚至早有人吗提出过相同的疑难《实在看无懂MSDN关于
Any 的讲》

为此我个人掌握啊是“确定集合中是否有素满足某同原则”。我们来瞧any其他用法:

务求:查询教了“张三”或“李四”的良师

贯彻代码:

图片 91

片栽艺术,以前我会习惯写第一种植。当然我们看好成了的sql和推行效率之后,看法改变了。

图片 92

频率的异竟产生近六倍

咱俩更比下count:

图片 93

图片 94

得出奇怪的下结论:

count(*)被你用老了呢(Any的用法)

求:查询是否留存名字也“张三”的学习者。(你的代码会怎么形容啊?)

图片 95

首先栽?第二栽?第三种植?呵呵,我先便是动的率先栽,然后有人说“你count被你用非常了”,后来本身想了想了怎么就让我为此特别了呢?直到对比了及时三只报告句子之习性后自知了。

图片 96

性的异竟生三百几近倍,count确实为自己因此异常了。(我思念,不止于自己一个人用十分了吧。)

咱看来地方的Any干嘛的?官方说是:

图片 97

自家再三读之中文说,一直无法知道。甚至早有人吗提出了千篇一律的疑团《实际上看不懂MSDN关于
Any
的说》

用自己个人掌握呢是“确定集合中是否有素满足某同条件”。我们来瞧any其他用法:

务求:查询教了“张三”或“李四”的良师

实现代码:

图片 98

个别栽艺术,以前我会习惯写第一种植。当然我们看那个成了的sql和施行效率之后,看法改变了。

图片 99

频率的异竟产生近六倍

咱们更比下count:

图片 100

图片 101

得出奇怪的下结论:

  1. 每当导航属性之中用count和动any性能分别不很,反而FirstOrDefault()
    != null的艺术性能最差。
  2. 以一直性判断其中any和FirstOrDefault() !=
    null性能分不殊,count性能如不等的几近。
  3. 故而,不管是直接性还是导航属性我们都用any来判定是否留存是极端稳妥的。

透明标识符

使由于各种原因我们用写下面这样逻辑的说话

图片 102

俺们可描绘成这样重复好

图片 103

看生成的sql就知了

图片 104

亚种植方式变通的sql要彻底得差不多,性能也重好。

晶莹剔透标识符

假如由于各种缘由我们需要写下面这样逻辑的语句

图片 105

我们可以描绘成这样又好

图片 106

看生成的sql就知晓了

图片 107

老二栽办法变通的sql要清得差不多,性能为再也好。

EntityFramework.Extended

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

尽酷的亮点就是是好一直批量改、删除,不用像EF默认的需先做询问操作。

至于官方EF为什么没提供这样的支撑就无懂得了。不过使用EntityFramework.Extended需要注意以下几点:

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();//回滚事务
    }
}

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的扩张。

 图片 108

图片 109

 

补充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#基础知识巩固系列》

欢迎热心园友补充!

http://www.bkjia.com/C\_jc/1281707.htmlwww.bkjia.comtruehttp://www.bkjia.com/C\_jc/1281707.htmlTechArticle【转】你必须知道的EF知识和经验,ef知识经验
【转】你要知道之EF知识和阅历
注意:以下内容如果无专门说明,默认使用的 EF6.0版本…

自从定义IQueryable扩展方法

 最后整理下从定义的IQueryable的壮大。

 图片 110

图片 111

 

补充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#基础知识巩固系列》

迎接热心园友补充!