您无法不了解的EF知识和经历

【转】你不可能不精通的EF知识和经历

瞩目:以下内容若无特意表明,暗中同意使用的EF6.0版本,code first情势。

在意:以下内容若无非常表明,暗中认可使用的EF6.0版本,code first形式。

推荐MiniProfiler插件

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

大家运用EF和在十分大程度升高了成本进度,然而随后拉动的是很多属性低下的写法和调换不太高速的sql。

纵然如此我们得以选择SQL Server
Profiler来监察和控制试行的sql,可是个人以为正是麻烦,每一趟须要开垦、过滤、清除、关闭。

在此处刚强推荐二个插件MiniProfiler。实时监督页面央浼对应实施的sql语句、推行时间。轻易、方便、针对性强。

如图:(切实运用和介绍请移步)

图片 1

推荐MiniProfiler插件

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

大家使用EF和在非常大程度进步了支出进程,不过随后带动的是众多质量低下的写法和转移不太高速的sql。

固然如此大家得以运用SQL Server
Profiler来监察和控制执行的sql,可是个人以为就是麻烦,每一遍须求开拓、过滤、清除、关闭。

在此地猛烈推荐二个插件MiniProfiler。实时监察和控制页面需要对应举行的sql语句、实行时间。轻易、方便、针对性强。

如图:(现实应用和介绍请移步)

图片 2

多少图谋

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

图片 3

背后会给出demo代码下载链接

数据准备

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

图片 4

背后会给出demo代码下载链接

foreach循环的陷进 

1.关于推迟加载

图片 5

请看上航海用体育场所红框。为啥StudentId有值,而Studet为null?因为使用code
first,供给设置导航属性为virtual,才会加载延迟加载数据。

图片 6

2.有关在循环中拜望导航属性的百般管理(接着上边,加上virtual后会报以下卓殊)

“已有开采的与此 Command 相关联的
DataReader,必须首先将它停业。”

图片 7

斩草除根方案:

  • 方案1、设定ConnectionString加上MultipleActiveResultSets=true,但只适用于SQL
    2006之后的本子
  • 方案2、也许先读出放置在List中

3.以上两点仅为热身,大家说的骗局才刚刚开头!

图片 8

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

图片 9

图片 10

建设方案:使用Include突显连续查询(注意:需求手动导入using System.Data.Entity
不然Include只可以传表名字符串)。

图片 11

再看迷你Profiler的督察(须臾间101条sql产生了1条,那其间的属性显而易见。)

图片 12

foreach循环的陷进 

1.关于推迟加载

图片 13

请看上海教室红框。为何StudentId有值,而Studet为null?因为使用code
first,需求设置导航属性为virtual,才会加载延迟加载数据。

图片 14

2.有关在循环中访问导航属性的老大处理(接着上边,加上virtual后会报以下十分)

“已有开采的与此 Command 相关联的
DataReader,必需首先将它停业。”

图片 15

焚薮而田方案:

  • 方案1、设定ConnectionString加上MultipleActiveResultSets=true,但只适用于SQL
    二零零六后头的本子
  • 方案2、恐怕先读出放置在List中

3.上述两点仅为热身,大家说的骗局才刚刚初步!

图片 16

然后大家点击展开MiniProfiler工具(不要被吓到)

图片 17

图片 18

施工方案:使用Include来得三回九转查询(注意:要求手动导入using System.Data.Entity
不然Include只可以传表名字符串)。

图片 19

再看MiniProfiler的监督检查(眨眼之间间101条sql形成了1条,那几个中的性子综上可得。)

图片 20

AutoMapper工具

上边我们经过Include展现的推行表的连接查询显明是不错的,但还远远不够。假设大家只供给查询数据的有个别字段呢,上边查询全体字段岂不是很浪费内部存款和储蓄器存款和储蓄空间和应用程序与数据库数据传输带宽。

大家能够:

图片 21

对应监督到的sql:

图片 22

我们看到变化的sql,查询的字段少了过多。独有大家彰显列出来字段的和多个StudentId,StudentId用来连接查询条件的。

精确,那样的秘技很科学。不过有未有何样越来越好的方案或格局啊?答案是迟早的。(不然,也不会在那边屁话了。)若是表字段相当多,大家须求动用的字段也要命多,导航属性也不行多的时候,那样的手动映射就展现不那么赏心悦目了。那么接下去大家开端介绍使用AutoMapper来产生映射:

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

图片 23

图片 24

大家见到上面查询语句未有多个个的手动映射,而映射都以单独布署了。当中CreateMap应该是要写到Global.asax文件之中的。(其实也等于分手了炫彩部分,清晰了查询语句。留意的校友恐怕注意到了,这种措施还免去了当仁不让Include)

图片 25

咱俩见到了变通的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

AutoMapper工具

地方大家透过Include呈现的试行表的连接查询显著是无庸置疑的,但还缺乏。如若大家只需求查询数据的少数字段呢,上边查询全部字段岂不是很浪费内部存储器存款和储蓄空间和应用程序与数据库数据传输带宽。

我们得以:

图片 26

对应监督到的sql:

图片 27

小编们看出变化的sql,查询的字段少了好多。独有我们浮现列出来字段的和贰个StudentId,StudentId用来连接查询条件的。

是的,那样的主意很不利。可是有未有怎样越来越好的方案或方法吗?答案是必然的。(不然,也不会在此地屁话了。)要是表字段非常多,大家要求选拔的字段也相当多,导航属性也非常多的时候,那样的手动映射就显得不那么难堪了。那么接下去大家开首介绍使用AutoMapper来实现映射:

在意:首先供给NuGet下载AutoMapper。(然后导入命名空间 using
AutoMapper; using AutoMapper.QueryableExtensions;)

图片 28

图片 29

大家看来下边查询语句十分的少个个的手动映射,而映射都是独立布署了。当中CreateMap应该是要写到Global.asax文件之中的。(其实也便是分手了光彩夺目部分,清晰了查询语句。留神的同班恐怕注意到了,这种艺术还免去了积极性Include)

图片 30

小编们看出了转换的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

联表查询总结

务求:查询前玖十四个学生考试体系(“模拟考试”、“正式考试”)、考试次数、语文平均分、学生姓名,且考试次数超越等于3次。(按考试项目分类总结)

代码如下:

图片 31

观察那般的代码,小编首先反馈是惨了。又在循环施行sql了。监察和控制如下:

图片 32

实际,大家只要求多少退换就把101条sql形成1条,如下:

图片 33

马上变1条。

图片 34

小编们开采查看详细的sql语句

图片 35

意识那仅仅只是查询结果集结而已,在那之中的按考试种类来总结是程序获得独具数据后在测算的(实际不是在数据库内总计,然后直接再次回到结果),那样平等是荒芜了数据库查询数据传输。

至于连接查询分组总计大家得以接纳SelectMany,如下:

图片 36

监察sql如下:(是还是不是精简多了啊?)

图片 37

关于SelectMany资料:

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

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

联表查询总结

务求:查询前一百个学生考试项目(“模拟考试”、“正式考试”)、考试次数、语文平均分、学生姓名,且考试次数当先等于3次。(按考试类别分类总结)

代码如下:

图片 38

看来这么的代码,作者首先感应是惨了。又在循环实施sql了。监控如下:

图片 39

实则,大家只要求有个别改动就把101条sql造成1条,如下:

图片 40

马上变1条。

图片 41

我们开采查看详细的sql语句

图片 42

发觉那仅仅只是查询结果集合而已,当中的按考试连串来总括是前后相继得到全体数据后在估测计算的(实际不是在数据库内总括,然后径直回到结果),那样平等是浪费了数据库查询数据传输。

有关连接查询分组计算大家能够利用SelectMany,如下:

图片 43

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

图片 44

关于SelectMany资料:

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

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

质量进步之AsNonUnicode

图片 45

监理到的sql

图片 46

小编们看出EF日常状态变化的sql会在头里带上“N”,假如大家抬高DbFunctions.AsNonUnicode生成的sql是未有“N”的,当您意识带上“N”的sql比未有带“N”的
sql查询速度慢比非常多的时候那就知道该怎么做。

(从前用oracle的时候带不带“N”查询功能差距非常显著,前天用sql
server测量试验并不曾发觉什么差别图片 47。还会有作者意识EF6会依照数据库中是nvarchar的时候才会生成带“N”的sql,oracle数据库没测量检验,有意思味的同室能够测量检验下)

属性提高之AsNonUnicode

图片 48

监察到的sql

图片 49

咱俩看到EF平时情状变化的sql会在前边带上“N”,假使我们增添DbFunctions.AsNonUnicode生成的sql是不曾“N”的,当你发掘带上“N”的sql比尚未带“N”的
sql查询速度慢比很多的时候那就了解该咋办。

(在此之前用oracle的时候带不带“N”查询作用差距极度分明,明天用sql
server测量试验并从未开掘什么样异样图片 50。还大概有本人发觉EF6会根据数据库中是nvarchar的时候才会生成带“N”的sql,oracle数据库没测量试验,风野趣的校友能够测验下)

质量升高之AsNoTracking

图片 51

大家看变化的sql

图片 52

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

图片 53

大家看变化的sql

图片 54

sql是浮动的千篇一律,可是实行时间却是4.8倍。原因仅仅只是第一条EF语句多加了一个AsNoTracking。

注意:

  • AsNoTracking干什么的吧?无追踪查询而已,也正是说查询出来的对象不能直接做修改。所以,我们在做多少集结查询呈现,而又无需对集中修改并更新到数据库的时候,一定不要遗忘加上AsNoTracking。
  • 一经查询进程做了select映射就没有必要加AsNoTracking。如:db.Students.Where(t=>t.Name.Contains(“张三”)).select(t=>new
    (t.Name,t.Age)).ToList();

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

渴求:查询名字里面富含“张三”的学生,先按名字排序,再按年龄排序。

图片 55

图片 56

哟,不对啊。按名字排序被年龄排序覆盖了。大家理应用ThenBy来组成排序。

图片 57

图片 58

不错不错,正是大家想要的效用。如若您不想用ThenBy,且都以升序的话,大家也能够:

图片 59

图片 60

转变的sql是一模一样的。与OrderBy、ThenBy对应的降序有OrderByDescending、ThenByDescending。

类似好像很全面了。其实不然,大家抢先百分之五十状态排序是动态的。举例,大家会越来越前端页面差异的操作供给差别字段的不等排序。那大家后台应该如何是好吧?

图片 61

本来,那样造成是没难题的,只要您愿意。能够那样多大概的判别有没有感到非凡SB?是的,大家本来有越来越好的减轻方案。纵然OrderBy能够一向传字符串???

杀鸡取卵方案:

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

图片 62

下一场上边又长又臭的代码能够写成:

图片 63

作者们看下生成的sql:

图片 64

和我们想要的效果完全符合,是或不是认为美美哒!!

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

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

务求:查询名字里面富含“张三”的学习者,先按名字排序,再按年龄排序。

图片 65

图片 66

嘿,不对啊。按名字排序被年龄排序覆盖了。大家应当用ThenBy来组合排序。

图片 67

图片 68

不错不错,便是大家想要的效应。如果你不想用ThenBy,且都以升序的话,大家也得以:

图片 69

图片 70

转移的sql是一律的。与OrderBy、ThenBy对应的降序有OrderByDescending、ThenByDescending。

类似好像很周密了。其实不然,大家大多数状态排序是动态的。例如,大家会越来越前端页面差异的操作须要不一样字段的不及排序。那咱们后台应该怎么办吗?

图片 71

当然,那样成功是没难点的,只要您愿意。能够那样多恐怕的推断有未有感觉非凡SB?是的,咱们自然有更加好的缓和方案。若是OrderBy能够直接传字符串???

缓解方案:

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

图片 72

然后上边又长又臭的代码能够写成:

图片 73

我们看下生成的sql:

图片 74

和我们想要的机能完全符合,是或不是深感美美哒!!

【注意】:传扬的排序字段前边要加排序关键字
asc或desc

lamdba条件构成

供给:依据分歧景观询问,恐怕景况

  1. 询问name=“张三” 的装有学生
  2. 查询name=“张三” 也许 age=18的保有学员

贯彻代码:

图片 75

是还是不是味到了扳平的恶臭图片 76。下边我们来灵活组装Lamdba条件。

斩草除根方案:

图片 77图片 78

这段代码笔者也是从网络偷的,具体链接找不到了。

下一场大家的代码能够写成:

图片 79

有未有美美哒一点图片 80。然后我们看看生成的sql是不是科学:

图片 81

lamdba条件构成

须要:依据分化意况询问,或然情状

  1. 询问name=“张三” 的享有学生
  2. 查询name=“张三” 只怕 age=18的持有学员

贯彻代码:

图片 82

是或不是味到了扳平的恶臭图片 83。下边我们来灵活组装Lamdba条件。

施工方案:

图片 84图片 85

这段代码作者也是从网络偷的,具体链接找不到了。

下一场咱们的代码能够写成:

图片 86

有未有美美哒一点图片 87。然后我们看看生成的sql是或不是科学:

图片 88

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的用法)

务求:查询是还是不是留存名称为“张三”的学员。(你的代码会怎么样写吧?)

图片 89

第一种?第两种?第三种?呵呵,笔者原先即是应用的率先种,然后有一些人会说“你count被您用坏了”,后来作者想了想了怎么就被本人用坏了啊?直到比较了那多少个语句的特性后本人了然了。

图片 90

属性之差竟有三百多倍,count确实被小编用坏了。(作者想,不仅被本人一人用坏了呢。)

大家看出上边包车型大巴Any干嘛的?官方表明是:

图片 91

自身频频阅读那么些粤语演讲,平昔不能领会。以至早有人也提议过同样的难题《实际上看不懂MSDN关于
Any
的表明

据此自身个人精晓也是“明确集合中是不是有成分满足某一规格”。我们来探视any别的用法:

渴求:查询教过“张三”或“李四”的导师

落到实处代码:

图片 92

二种艺术,在此在此以前俺会习贯写第一种。当然大家看看生成过的sql和施行效能之后,观念改换了。

图片 93

频率之差竟有近六倍

我们再对照下count:

图片 94

图片 95

得出奇异的结论:

  1. 在导航属性之中使用count和动用any品质分别相当的小,反而FirstOrDefault()
    != null的不二等秘书诀品质最差。
  2. 在间接属性决断在那之中any和FirstOrDefault() !=
    null质量分别一点都不大,count质量要差的多。
  3. 之所以,不管是向来属性依然导航属性大家都用any来推断是或不是留存是最妥当的。

count(*)被你用坏了吗(Any的用法)

供给:查询是不是存在名为“张三”的学生。(你的代码会怎么样写啊?)

图片 96

率先种?第二种?第三种?呵呵,我原先就是选拔的第一种,然后有人讲“你count被你用坏了”,后来自家想了想了怎么就被我用坏了吧?直到相比了那三个语句的习性后作者精晓了。

图片 97

个性之差竟有三百多倍,count确实被本人用坏了。(作者想,不仅被笔者一个人用坏了啊。)

小编们看出上边的Any干嘛的?官方表明是:

图片 98

自身屡次阅读那一个汉语演说,一直不或许明白。以致早有人也建议过一模一样的难点《实在看不懂MSDN关于
Any
的演讲

据此笔者个人知道也是“确定集结中是还是不是有成分知足某一标准”。我们来看看any别的用法:

供给:查询教过“张三”或“李四”的教师的资质

兑今世码:

图片 99

两种方法,以前小编会习贯写第一种。当然大家看看生成过的sql和施行效用之后,观念改造了。

图片 100

频率之差竟有近六倍

笔者们再对照下count:

图片 101

图片 102

得出奇异的结论:

  1. 在导航属性之中使用count和采纳any品质分别十分的小,反而FirstOrDefault()
    != null的格局品质最差。
  2. 在一直属性判别个中any和FirstOrDefault() !=
    null质量分别十分的小,count品质要差的多。
  3. 于是,不管是间接属性照旧导航属性大家都用any来决断是不是留存是最稳当的。

晶莹剔透标志符

倘诺由于各样原因大家必要写上面那样逻辑的言辞

图片 103

大家得以写成这么越来越好

图片 104

看生成的sql就精晓了

图片 105

第三种艺术生成的sql要深透得多,质量也越来越好。

晶莹剔透标记符

假如由于各个缘由我们供给写上边那样逻辑的言语

图片 106

笔者们可以写成这么更加好

图片 107

看生成的sql就精晓了

图片 108

其次种格局变通的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();//回滚事务
    }
}

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

 图片 109

图片 110

 

补充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#基础知识巩固种类

应接热心园友补充!

自定义IQueryable扩张方法

 最终整理下自定义的IQueryable的恢宏。

 图片 111

图片 112

 

补充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#基础知识加强体系

应接热心园友补充!