.NET中的EF效率问题

.NET中的EF效率问题,第1张

我不是大神,但是你这个问题我有点思路,从MSDN(https://msdn.microsoft.com/zh-CN/library/cc853327.aspx)上可以看到影响EF性能的因素

第二种很快是因为dbcontext没有追踪你执行查询的结果(dbconext.Database.SqlQuery<int>("select count(*) from table")),你对这个结果附加where条件是不会加到EF生成的SQL语句上的

所以对于第一种情况,你可以使用NoTracking(dbconext.table.AsNoTracking().Count())来取消EF对结果的追踪

具体的区别你可以参考:

http://www.cnblogs.com/haogj/archive/2011/05/08/2040196.html

和:

http://www.cnblogs.com/LingzhiSun/archive/2011/04/27/EF_Trick4.html

说EF性能差的,目测是根本不会使用EF的,或者说是把EF用的的很烂的人。

EF目前是6.1.3。针对code first以及SQL脚本优化做了非常多的工作。举个简单的例子。现在估计还有大部分.NET程序员在使用数据脚本分页的时候还在用着古老的top分页吧?好一点的知道row_number。但是EF会根据你连接SQL版本(仅讨论SQLserver)进行不同版本的分页支持。例如sql2012以上的版本。EF会自动采用FETCH NEXT进行分页,fn和top的性能对比,这个就不说了。

再举个例子。之前给公司某同事擦屁股,有一个多表多关联复杂查询并且内部要实现一些函数 *** 作。采用linq to ef编写的。测试反馈说查询速度巨慢。我打开sql profile看了一下。此君接近90行的linq,生成了2000行的SQL。于是我逐步重写。最后变为40行的Linq,生成60行的脚本,打开速度立马飞跃到毫秒级。

以上是说的读取性能方面的问题。下面说一下写的问题,目前EF对批量写批量UP *** 作的确支持不是很好(不要提addrange) 但是可以通过第三方EF插件实现对数据库的bulk *** 作。大量写的效率基本和在sql里进行bulk几乎差不多。

所以不是EF性能不好,而是你不会用罢了

A、新特性

a、支持对关系型数据的批量更新。 什么意思就不用细说了吧,在这之前,很多人喷粪EF,就是说他的更新效率太低,如果要实现批量更新,特别插入时,需要借助sql语句或是第三方工具类。相信这是很多人期待的功能;

b、支持唯一约束。它允许你在实体内除主键外额外标识一个键,将他们用作外键。

B、行为(Behavior)改变

在EF6和前期的版本中,顶层API就有很多不直观的行为,虽然EF7尽可能是保持顶层API的相同,但仍去掉了一些限制并添加了一些我们期待的行为。什么意思呢?这听起来有点迷糊,举个例子来说明吧,以前的查询,虽然Linq给我们带来了很大方便,但限制多呀,整个Linq查询翻译成一条单独的sql查询,Linq查询中只能包含EF能翻译成sql的语句或方法;还有就是sql的生成,有时生成了很复杂、效率不高,且不是我们希望的sql语句。EF7改变这种情况,可以返回多结果集,sql评估工作也不是在数据库端来做了,变更到客户端。这样就为生成sql提供了很大的灵活性。如果还有点晕,没关系,先有个印象就行。

C、变得更加简单、灵活

直接使用一个例子来说明吧。我们想通过EF的元数据来获取Blog实体被映射到数据库中的哪一张表。在这之前,我们的代码会是这样:

在EF7中会代码会是这样:

using (var db = new BloggingContext())

{

var tableName = db.Model.GetEntityType(typeof(Blog)).Relational().Table

}

 D、去掉了一些特性

a、每类型映射多个实体集(MEST)。这个特性,估计用的人很少,正是因为使用的人少,所以才去掉。它是什么意思呢?就是一个类型对应数据库中的多张表,例如:表Product 和 RetriedProduct都映射到Product类。如果你还有这样的需求,使用继承是更好的选择。

b、非常复杂的类型映射。在EF6.x中,可能在一个继承映射中组合了TPH,TPT和TPC。EF7不再支持这种复杂的映射了,它要求你的CLR 类型尽量跟表结构保持一至。至于为什么,我相同不少人到现在都还没有弄明白什么是TPH,TPT,TPC,那更说不上灵活运行了,这也是导致EF6.x MetadataWorkspace异常复杂的主要原因。

c、去掉edmx建模。这可能会让很多人失望,因为它曾经给我们带来多么美好的回忆。但它有很多的不足,比较一些复杂的需求,不适应ddd分层设计,不符合现在流行的POCO等。最主要的是,有更好的选择code-based建模,这就是我们常说的code-first。 可能你会有疑问,怎么code-first和edmx是平级概念,它不是跟db-first、model-first平级的吗? 没错,它是跟edmx平级的,更详细的解释请查看我的另一篇博客Code First is a bad name,这些年我们对Code First的理解都错了 !很震惊吧?

d、去掉ObjectContext API。它陪EF一起成长,到EF4.1时才被DbContext弄到幕后.不过DbContext只是它的外观模式,底层仍然是使用的它。有时需要使用一些高级的功能时,我们还想办法把它找出来。去掉它并不意味着它以前的一些功能不能用了。EF7重写了底层,把之前一定需要它才能使用的api包含在了DbContext中,并且调用更加清晰,简单。

e、去掉了延迟加载。 这功能相信大家不陌生,它一直被当成EF的一大特点,但现在,它将要从EF7中去掉。我不确定最终的版本微软会不会把它请回来,因为这一点存在很大的争论。无论是我们这些开发人员,还是EF的开发团队。我个人是支持去掉的。一,不是所有的应用都需要延迟加加载;二、不少的EF使用者对它没有深入的去了解,经常会有人问,为什么会出现"无法完成该 *** 作,因为 DbContext 已释放"这样的问题。这说明这个功能反而给一部份使用者带来了困惑。

这些变化并不是最终的,也许文中说的,会发生改变。当然这里也不可能列出所有的变化点,毕竟EF7还在处于开发过程中。总之,它是一个革命性的版本,以至于有人在争论应该叫他EF7呢,还是EF1。

E、对非关系型数据库的支持,文章开头部分已经有提到,这里就不多说了。

四、EF7的开发计划

相信,很多人和我一样,去年就开始期待EF7的发布。一年多长长的等待,可是它还没有出来,到底要什么时候呢?微软的计划是2016年,所以大家得耐心等待。不过,有个好消息是,它是开源的,最新的源代码在github上,如果你想了解更多的细节,可以到下面的地址(https://github.com/aspnet/EntityFramework)去克隆或是下载源代码。下面是EF的开发计划表


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/bake/11520352.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-16
下一篇2023-05-16

发表评论

登录后才能评论

评论列表(0条)

    保存