C++【转】你必须清楚的EF知识和经验

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

foreach循环的陷进 

1.有关延迟加载

C++ 1

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

C++ 2

2.关于在循环中访问导航属性的要命处理(接着下边,加上virtual后会报以下卓殊)

“已有打开的与此 Command 相关联的
DataReader,必须首先将它倒闭。”

C++ 3

釜底抽薪方案:

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

3.之上两点仅为热身,大家说的牢笼才刚刚起初!

C++ 4

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

C++ 5

C++ 6

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

C++ 7

再看MiniProfiler的监察(瞬间101条sql变成了1条,这里面的性质不问可知。)

C++ 8

性能提高之AsNoTracking

C++ 9

咱俩看变化的sql

C++ 10

sql是转变的一模一样,但是执行时间却是4.8倍。原因仅仅只是第一条EF语句多加了一个AsNoTracking。

注意:

  • AsNoTracking干什么的吗?无跟踪查询而已,也就是说查询出来的靶子不可能直接做修改。所以,我们在做多少集合查询展现,而又不需要对聚集修改并革新到数据库的时候,一定毫无忘记加上AsNoTracking。
  • 假设查询过程做了select映射就不需要加AsNoTracking。如:db.Students.Where(t=>t.Name.Contains(“张三”)).select(t=>new
    (t.Name,t.Age)).ToList();

属性提升之AsNonUnicode

C++ 11

监理到的sql

C++ 12

咱俩看看EF正常境况变化的sql会在前方带上“N”,借使我们添加DbFunctions.AsNonUnicode生成的sql是未曾“N”的,当你意识带上“N”的sql比从来不带“N”的
sql查询速度慢很多的时候这就通晓该肿么办。

(从前用oracle的时候带不带“N”查询效率差异特别彰着,明日用sql
server测试并没有发觉怎么区别C++ 13。还有自己发觉EF6会依照数据库中是nvarchar的时候才会生成带“N”的sql,oracle数据库没测试,有趣味的校友可以测试下)

【转】你必须领悟的EF知识和阅历

lamdba条件构成

渴求:遵照不同情状询问,可能意况

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

心想事成代码:

C++ 14

是不是味到了同一的臭气C++ 15。下边我们来灵活组装Lamdba条件。

釜底抽薪方案:

C++ 16C++ 17

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

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

C++ 18

有没有美美哒一点C++ 19。然后大家看看生成的sql是否正确:

C++ 20

推荐MiniProfiler插件

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

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

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

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

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

C++ 21

晶莹剔透标识符

假设由于各样缘由咱们需要写下边那样逻辑的说话

C++ 22

咱俩得以写成这么更好

C++ 23

看生成的sql就领会了

C++ 24

第二种艺术变通的sql要干净得多,性能也更好。

count(*)被您用坏了呢(Any的用法)

要求:查询是否留存名字为“张三”的学员。(你的代码会咋样写啊?)

C++ 25

第一种?第两种?第二种?呵呵,我原先就是行使的第一种,然后有人说“你count被您用坏了”,后来自我想了想了怎么就被自己用坏了吧?直到比较了这两个语句的性质后我晓得了。

C++ 26

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

咱俩来看地点的Any干嘛的?官方解释是:

C++ 27

我频繁阅读这些中文演说,平昔不能知晓。甚至早有人也指出过相同的问号《实则看不懂MSDN关于
Any
的解释

由此自己个人通晓也是“确定集合中是否有元素满意某一原则”。我们来探视any其他用法:

务求:查询教过“张三”或“李四”的民办教授

落实代码:

C++ 28

二种办法,以前我会习惯写第一种。当然我们看看生成过的sql和执行效能之后,看法改变了。

C++ 29

频率之差竟有近六倍

我们再对照下count:

C++ 30

C++ 31

得出奇怪的定论:

  1. 在导航属性之中使用count和使用any性能分别不大,反而FirstOrDefault()
    != null的办法性能最差。
  2. 在直接属性判断其中any和FirstOrDefault() !=
    null性能分别不大,count性能要差的多。
  3. 为此,不管是直接属性还是导航属性大家都用any来判断是否存在是最稳妥的。

自定义IQueryable扩大方法

 最终整理下自定义的IQueryable的扩张。

 C++ 32

C++ 33

 

补充1:

C++,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#基础知识巩固序列

欢迎热心园友补充!

EF的预热

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

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

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

C++ 34

C++ 35

哎呀,不对啊。按名字排序被年龄排序覆盖了。我们应有用ThenBy来组合排序。

C++ 36

C++ 37

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

C++ 38

C++ 39

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

接近好像很系数了。其实不然,大家大部分情景排序是动态的。比如,我们会愈来愈前端页面不同的操作要求不同字段的不比排序。这我们后台应该如何做吧?

C++ 40

自然,这样形成是没问题的,只要你愿意。可以如此多或者的判断有没有感觉卓殊SB?是的,我们自然有更好的化解方案。要是OrderBy可以一贯传字符串???

化解方案:

  1. guget下载System.Linq.Dynamic 
  2. 导入System.Linq.Dynamic命名空间
  3. 编制OrderBy的恢弘方法

C++ 41

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

C++ 42

大家看下生成的sql:

C++ 43

和大家想要的机能完全符合,是不是深感美美哒!!

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

联表查询总括

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

代码如下:

C++ 44

看看这样的代码,我先是反馈是惨了。又在循环执行sql了。监控如下:

C++ 45

事实上,大家只需要有些改变就把101条sql变成1条,如下:

C++ 46

马上变1条。

C++ 47

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

C++ 48

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

至于连接查询分组总括我们得以行使SelectMany,如下:

C++ 49

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

C++ 50

关于SelectMany资料:

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

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

留意:以下内容假设没有专门表明,默认使用的EF6.0版本,code first模式。

数量准备

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

C++ 51

前面会给出demo代码下载链接

AutoMapper工具

地方我们通过Include显示的执行表的接连查询显然是毋庸置疑的,但还不够。要是我们只需要查询数据的一些字段呢,下边查询所有字段岂不是很浪费内存存储空间和应用程序与数据库数据传输带宽。

俺们可以:

C++ 52

对应监督到的sql:

C++ 53

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

没错,这样的主意很不错。可是有没有哪些更好的方案或艺术吧?答案是毫无疑问的。(不然,也不会在此处屁话了。)倘诺表字段异常多,我们需要拔取的字段也非凡多,导航属性也万分多的时候,这样的手动映射就显得不那么难堪了。那么接下去我们起头介绍使用AutoMapper来完成映射:

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

C++ 54

C++ 55

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

C++ 56

我们看看了转移的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