加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

你必须知道的EF知识和经验

发布时间:2020-12-15 04:44:01 所属栏目:百科 来源:网络整理
导读:数据准备 新建实体:Score(成绩分数表)、Student(学生表)、Teacher(老师表) foreach循环的陷进? 1.关于延迟加载 2.关于在循环中访问导航属性的异常处理( ) 解决方案: 方案1、设定ConnectionString加上MultipleActiveResultSets=true,但只适用于SQL

数据准备

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

foreach循环的陷进?

1.关于延迟加载

2.关于在循环中访问导航属性的异常处理(

解决方案:

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

3.以上两点仅为热身,我们说的陷阱才刚刚开始!

然后我们点击打开MiniProfiler工具(

解决方案:使用Include显示连接查询()。

再看MiniProfiler的监控(

AutoMapper工具

上面我们通过Include显示的执行表的连接查询显然是不错的,但还不够。如果我们只需要查询数据的某些字段呢,上面查询所有字段岂不是很浪费内存存储空间和应用程序与数据库数据传输带宽。

我们可以:

对应监控到的sql:

我们看到生成的sql,查询的字段少了很多。只有我们显示列出来字段的和一个StudentId,StudentId用来连接查询条件的。

是的,这样的方式很不错。可是有没有什么更好的方案或方式呢?答案是肯定的。()如果表字段非常多,我们需要使用的字段也非常多,导航属性也非常多的时候,这样的手动映射就显得不那么好看了。那么接下来我们开始介绍使用AutoMapper来完成映射:

我们看到上面查询语句没有一个个的手动映射,而映射都是独立配置了。

我们看到了生成的sql和前面有些许不同,但只生成了一条sql,并且结果也是正确的。()

这样做的好处?

  1. 避免在循环中访问导航属性多次执行sql语句。
  2. 避免了查询语句中太多的手动映射,影响代码的阅读。

关于AutoMapper的其他一些资料:

联表查询统计

要求:查询前100个学生考试类型()、考试次数、语文平均分、学生姓名,且考试次数大于等于3次。(

代码如下:

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

其实,我们只需要,如下:

马上变1条。

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

发现这仅仅只是查询结果集合而已,其中的按考试类型来统计是程序拿到所有数据后在计算的(),这样同样是浪费了数据库查询数据传输。

关于连接查询分组统计我们可以使用SelectMany,如下:

监控sql如下:(

关于SelectMany资料:

性能提升之AsNonUnicode

监控到的sql

我们看到EF正常情况生成的sql会在前面带上“N”,如果我们加上DbFunctions.AsNonUnicode生成的sql是没有“N”的,当你发现带上“N”的sql比没有带“N”的 sql查询速度慢很多的时候那就知道该怎么办。

性能提升之AsNoTracking

我们看生成的sql

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

注意:

  • AsNoTracking干什么的呢?无跟踪查询而已,也就是说查询出来的对象不能直接做修改。所以,我们在做数据集合查询显示,而又不需要对集合修改并更新到数据库的时候,一定不要忘记加上AsNoTracking。
  • 如果查询过程做了select映射就不需要加AsNoTracking。如:db.Students.Where(t=>t.Name.Contains("张三")).select(t=>new (t.Name,t.Age)).ToList();

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

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

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

不错不错,正是我们想要的效果。如果你不想用ThenBy,且都是升序的话,我们也可以:

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

看似好像很完美了。其实不然,我们大多数情况排序是动态的。比如,我们会更加前端页面不同的操作要求不同字段的不同排序。那我们后台应该怎么做呢?

当然,这样完成是没问题的,只要你愿意。可以这么多可能的判断有没有感觉非常SB?是的,我们当然有更好的解决方案。要是OrderBy可以直接传字符串???

解决方案:

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

然后上面又长又臭的代码可以写成:

我们看下生成的sql:

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

【注意】:

lamdba条件组合

要求:根据不同情况查询,可能情况

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

实现代码:

是不是味到了同样的臭味

解决方案:

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

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

有没有美美哒一点

EF的预热

count(*)被你用坏了吗

要求:查询是否存在名字为“张三”的学生。(

第一种?第二种?第三种?呵呵,我以前就是使用的第一种,然后有人说“你count被你用坏了”,后来我想了想了怎么就被我用坏了呢?直到对比了这三个语句的性能后我知道了。

性能之差竟有,count确实被我用坏了。(

我们看到上面的Any干嘛的?官方解释是:

我反复阅读这个中文解释,一直无法理解。甚至早有人也提出过同样的疑问《》

所以我个人理解也是“”。我们来看看any其他用法:

要求:查询教过“张三”或“李四”的老师

实现代码:

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

效率之差竟有

我们再对比下count:

得出奇怪的结论:

  1. 在导航属性里面使用count和使用any性能区别不大,反而FirstOrDefault() != null的方式性能最差。
  2. 在直接属性判断里面any和FirstOrDefault() != null性能区别不大,count性能要差的多。
  3. 所以,

透明标识符

假如由于各种原因我们需要写下面这样逻辑的语句

我们可以写成这样更好

看生成的sql就知道了

第二种方式生成的sql要干净得多,性能也更好。

EntityFramework.Extended

这里推荐下插件EntityFramework.Extended,看了下,很不错。

最大的亮点就是可以直接批量修改、删除,不用像EF默认的需要先做查询操作。

至于官方EF为什么没有提供这样的支持就不知道了。不过使用EntityFramework.Extended需要注意以下几点:

  1. ()

在此纠正个问题EntityFramework.Extended并不是说不能回滚,感谢@园友的指正()。

?;

测试代码如下:(如果注释掉手抛异常代码是可以直接更新到数据库的)

( ctxTransaction ==> ).Update(t => Teacher { Age = </span><span style="color: #0000ff;"&gt;throw</span> <span style="color: #0000ff;"&gt;new</span> Exception(<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;手动抛出异常</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;); ctxTransaction.Commit();</span><span style="color: #008000;"&gt;//</span><span style="color: #008000;"&gt;提交事务</span>

<span style="color: #000000;"> }
<span style="color: #0000ff;">catch<span style="color: #000000;"> (Exception)
{
ctxTransaction.Rollback();<span style="color: #008000;">//<span style="color: #008000;">回滚事务
<span style="color: #000000;"> }
}

自定义IQueryable扩展方法

?最后整理下自定义的IQueryable的扩展。

?

补充1:

First和Single的区别:前者是

补充2:?

已打包nuget提供直接安装??或nuget搜索??

结束:

源码下载:

本文以同步至《》

欢迎热心园友补充!

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读