【转】你不可以不掌握的EF知识和阅历

【转】你无法不精通的EF知识和阅历

1.国语乱码问题

注意:以下内容要是没有专门表达,默认使用的EF6.0版本,code first格局。

     
 利用ef更新数据到mysql数据库中,中文就会变成乱码”???”,尽管把mysql的数据库的编码设置为”utf8″也会成为乱码,从网上查询了下,

推荐MiniProfiler插件

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

我们利用EF和在很大程度提高了付出进度,可是随着带来的是不少特性低下的写法和转移不太高速的sql。

虽说我们得以应用SQL Server
Profiler来监控实施的sql,不过个人认为就是麻烦,每一趟需要开辟、过滤、清除、关闭。

在此处强烈推荐一个插件MiniProfiler。实时监督页面请求对应实施的sql语句、执行时间。简单、方便、针对性强。

如图:(具体运用和介绍请移步)

图片 1

  在数量连接字符串后边加上:Character Set=utf8;即可,那样插入mysql的粤语就不会成为乱码了。 

数量准备

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

图片 2

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

图片 3

foreach循环的陷进 

1.有关延迟加载

图片 4

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

图片 5

2.有关在循环中走访导航属性的特别处理(接着下面,加上virtual后会报以下极度)

“已有打开的与此 Command 相关联的
Data里德(Reade)r,必须首先将它倒闭。”

图片 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

 

AutoMapper工具

下面我们通过Include显示的执行表的连天查询分明是科学的,但还不够。假如大家只需要查询数据的某些字段呢,下边查询所有字段岂不是很浪费内存存储空间和应用程序与数据库数据传输带宽。

我们可以:

图片 12

对应监督到的sql:

图片 13

大家见到变化的sql,查询的字段少了成千上万。唯有大家来得列出来字段的和一个StudentId,StudentId用来连续查询条件的。

科学,这样的模式很不错。不过有没有什么样更好的方案或艺术吧?答案是一定的。(不然,也不会在这边屁话了。)倘使表字段分外多,大家需要使用的字段也充分多,导航属性也丰硕多的时候,这样的手动映射就体现不那么窘迫了。那么接下去我们初步介绍使用AutoMapper来成功映射:

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

图片 14

图片 15

大家来看下面查询语句没有一个个的手动映射,而映射都是单身布置了。其中CreateMap应该是要写到Global.asax文件之中的。(其实也就是分离了炫耀部分,清晰了查询语句。细心的同班也许注意到了,这种办法还免去了当仁不让Include)

图片 16

咱俩看看了变化的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

2.HTML文书乱码问题

联表查询总结

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

代码如下:

图片 17

见到这般的代码,我第一反响是惨了。又在循环执行sql了。监控如下:

图片 18

骨子里,咱们只需要多少改变就把101条sql变成1条,如下:

图片 19

马上变1条。

图片 20

大家开拓查看详细的sql语句

图片 21

发觉这仅仅只是查询结果集合而已,其中的按考试体系来总括是先后得到所有数据后在测算的(而不是在数据库内总结,然后径直回到结果),这样平等是浪费了数据库查询数据传输。

关于连接查询分组总结大家得以行使SelectMany,如下:

图片 22

督查sql如下:(是不是简单多了吗?)

图片 23

关于SelectMany资料:

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

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

  后台编辑图片、视频、连接等富文本时,大家也会采纳ueditor等富文本编辑器,不过存储到mysql中就会成为乱码.

属性提升之AsNonUnicode

图片 24

监察到的sql

图片 25

咱俩看来EF正常情状变化的sql会在前方带上“N”,假诺我们添加DbFunctions.AsNonUnicode生成的sql是一贯不“N”的,当您发现带上“N”的sql比尚未带“N”的
sql查询速度慢很多的时候那就了解该怎么做。

(往日用oracle的时候带不带“N”查询效能差距特别明确,前日用sql
server测试并从未发现什么样差别图片 26。还有自己发觉EF6会依据数据库中是nvarchar的时候才会生成带“N”的sql,oracle数据库没测试,有趣味的同桌可以测试下)

  只需要修改mysql对应的字段类型为:longtext即可

属性提高之AsNoTracking

图片 27

俺们看变化的sql

图片 28

sql是变化的一模一样,不过实施时间却是4.8倍。原因仅仅只是第一条EF语句多加了一个AsNoTracking。

注意:

  • AsNoTracking干什么的啊?无跟踪查询而已,也就是说查询出来的目的无法一贯做修改。所以,大家在做多少集合查询呈现,而又不需要对聚集修改并革新到数据库的时候,一定毫无忘记加上AsNoTracking。
  • 倘若查询过程做了select映射就不需要加AsNoTracking。如:db.Students.Where(t=>t.Name.Contains(“张三”)).select(t=>new
    (t.Name,t.Age)).ToList();

  图片 29

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

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

图片 30

图片 31

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

图片 32

图片 33

不错不错,正是我们想要的效能。假诺你不想用ThenBy,且都是升序的话,我们也得以:

图片 34

图片 35

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

仿佛好像很周密了。其实不然,我们大部分场所排序是动态的。比如,咱们会进一步前端页面不同的操作要求不同字段的两样排序。这我们后台应该咋做啊?

图片 36

理所当然,这样形成是没问题的,只要你愿意。可以这么多或者的论断有没有痛感那么些SB?是的,大家当然有更好的解决方案。假设OrderBy可以平昔传字符串???

釜底抽薪方案:

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

图片 37

接下来下边又长又臭的代码可以写成:

图片 38

咱俩看下生成的sql:

图片 39

和我们想要的效率完全符合,是不是觉得美美哒!!

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

 

lamdba条件构成

渴求:遵照不同景观询问,可能意况

  1. 询问name=“张三” 的保有学生
  2. 询问name=“张三” 或者 age=18的享有学生

贯彻代码:

图片 40

是不是味到了扳平的臭味图片 41。下边大家来灵活组装Lamdba条件。

化解方案:

图片 42图片 43

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

然后我们的代码可以写成:

图片 44

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

图片 46

EF的预热

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

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

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

图片 47

首先种?第二种?第两种?呵呵,我原先就是运用的第一种,然后有人说“你count被你用坏了”,后来自家想了想了怎么就被自己用坏了吗?直到比较了这六个语句的性质后自己驾驭了。

图片 48

性能之差竟有三百多倍,count确实被我用坏了。(我想,不止被自己一个人用坏了吗。)

我们见到下面的Any干嘛的?官方解释是:

图片 49

本人多次阅读这些中文表达,平昔无法领会。甚至早有人也指出过一样的问号《其实看不懂MSDN关于
Any
的演讲

因而我个人精通也是“确定集合中是否有元素满意某一条件”。我们来看望any其他用法:

要求:查询教过“张三”或“李四”的先生

落实代码:

图片 50

二种情势,往日我会习惯写第一种。当然大家看看生成过的sql和推行效能之后,看法改变了。

图片 51

频率之差竟有近六倍

我们再对照下count:

图片 52

图片 53

得出奇怪的结论:

  1. 在导航属性之中使用count和行使any性能分别不大,反而FirstOrDefault()
    != null的法子性能最差。
  2. 在一向属性判断其中any和FirstOrDefault() !=
    null性能分别不大,count性能要差的多。
  3. 于是,不管是平昔属性依旧导航属性大家都用any来判断是否留存是最稳妥的。

透明标识符

要是由于各类原因我们需要写下边那样逻辑的说话

图片 54

大家可以写成这么更好

图片 55

看生成的sql就明白了

图片 56

第二种方法变通的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的扩大。

 图片 57

图片 58

 

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

迎接热心园友补充!