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

欢迎热心园友补充!

相关文章