【转】你必须懂得之EF知识和经验。【转】你得明白之EF知识及更,ef知识更。

【转】你必须了解之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#基础知识巩固系列》

迎接热心园友补充!

相关文章

admin

网站地图xml地图