Nhibernate开发专题博客

Nhibernate开发专题博客,为您精选Nhibernate开发教程,助您开发愉快!

公告信息
欢迎光临Nhibernate开发专题博客,祝您开发愉快!
文章档案

NHibernate3 EF性能比较及优缺点分析对比

上文:NHibernate3 EF性能比较NH的爱好者或者开发者,针对性能测试中NH没有做优化,而大打出手,今天,就针对这些观点进行一个分析对比:

当年(09年)几乎同一时期,又有一哥们进行了EF vs NH的性能测试。结果类似,NH惨败。NH大牛们于是又站出来喷,哥们赶紧又发了一篇,包含了大牛们给出的优化方案。其实从图上来看,NH还是败了的,但是哥们还是很违心的(大雾)出来搅混水说“性能差不多”,“性能并不是我们的唯一追求”之类的。

从上面这两档子事儿可以看出来,NH在拥有强大扩展能力的同时学习曲线也是比较高的。还有就是NH大牛们肚量实在是。。。抱歉这一段我不能用英语(你根本没这个能耐好伐?

于是本文让我们把性能这一篇儿翻过去,只是单纯的看看大家对两个框架的看法。括号中含一些个人吐槽

  • 首先还是来看来自NH的Oren Eini大牛的观点。

InfoQ中文版给出了原文大意以及一些精彩吐槽的翻译。我只能说NH大牛果然又不淡定了。InfoQ英文版里也有一些不错的吐槽,从技术到项目本身。从总体上来讲这些吐槽是倾向于支持NH的,但是也有一些犀利的观点认为NH没有公司支持,早晚会被EF超越。注意当时NH3和EF4.1都还未发布,一些观点可能已经不适用。摘抄一些如下:

大牛的观点是:

NH支持

  • 批量写入
  • 批量读/多重查询特性(我理解是在说Future?)
  • 批量的集合加载
  • 带有lazy="extra"的集合
  • 集合过滤器和分页集合
  • 二级缓存(实际上NH的二级缓存貌似也很简单?)
  • 调整
  • 集成和扩展性

EF的优点在于

  • Linq(NH3.0的Linq支持有不错的进展)
  • EF属于微软

一些吐槽:

  • NH的错误信息太差(这个确实。感觉上你想明白NH的异常在说什么就要理解它的实现机制,也许读过《企业应用架构模式》会好一些?)
  • EF的文档更好(NH的文档真的狠orz,很多照抄了java版的不说,连实际上存在的feature都没有介绍。。。),但是NH的社区支持更多(其实NH的问题确实能一搜结果一堆,但是很多都帮助有限。。。。。。)
  • EF支持变更跟踪
  • NH更好的支持UT
  • EF有很好的设计器
  • 设计器神马的都是歪门邪道,微软的强类型DataSet也有设计器还不是渣(DataSet躺着也中枪啊。。。)
  • NH的一个很大缺陷是不能load部分的对象图(我理解这个意思是说EF有include?NH也能fetch啊?)。NH的懒加载也许是一个解决方案但一般只能支持两层模型(App+DB)而EF支持n层模型
  • NH的Iesi.Collections在WCF的序列化中有问题,而且ISet没有indexer(ISet为啥要有indexer啊。。。要indexer就用IList好了么。。。话说NH啥时候完全迁移到.Net4就能抛弃Iesi.Collections了)
  • 还是加载对象图的问题。EF有能力在一个Query中完成(但是也有人说这个Query的性能很差,比如说很多column都是重复数据),而NH连在一次数据库访问中完成都做不到,不论我用Fetch还是Future。
  • NH的学习曲线陡。IDE支持也不好,除了NH本身可能还需要熟悉一些其他的OSS
  • NH没有投资人。也就是说bug fix速度,新版本开发速度等等都得不到保障。
  • 对和其他ORM的对比,EF官方好像没什么回应。(可以理解为笑而不语么。。。)
  • 接下来看看stack overflow上的评价

在stack overlow上,EF vs NH是一个常被问及的问题。总体上来讲,因为该站NH经验丰富的人比较多,多以NH的好话比较多。在EF的早期年代,喷EF不支持POCO的人是超多的,直到最近也有人狂喷EF称其比起NH还处在石器时代。不过比较平和的说法是EF比起NH在扩展性上差太多。(这一段不是翻译完全是我的吐槽)

 

之后网上也有很多blog post。可以选择性的看看,其实喷的内容大同小异。注意不要看太老的,对EF不公平(虽然NH3也出了,但是相关的对比文章太少了没办法)。推荐Dino Esposito的一个系列文章。这个系列从多数据库支持、懒加载、Fetch、二级缓存、Self-tracking entities、Queries六个方面进行了比较。从基调上,Dino Esposito是给微软写书的,说EF好话多一些。。。另外这个系列比较新,写的时候NH3都快出了。

 

多数据库支持

这个问题有两个内容:一是支持多种数据库,二是同一Application内同时使用多个数据库。对于前者作者含蓄的支出了EF需要第三方支持。后者的问题上二者都有解决办法。

懒加载

EF只能支持对navigation property的懒加载。而且是context范围的,runtime控制。(不过后面作者又补了一句说如果使用POCO model,使用proxy,virtual property都可以懒加载。。。不知道哪个对。。。)

NH通过配置实现懒加载,可以精确到property级别。但是不知道能不能runtime控制。

Fetch

EF的Fetch是通过runtime调用Include方法。实现上基本上是翻译成一个OUTER JOIN

NH的Fetch是通过SetFetchMode实现(这里我插一句,作者这里讲的是用Criteria API的方式,用HQL的话可以直接写fetch,用Linq的话还没试过。。。)。有JOIN和SELECT两种mode。后者是通过另一个SELECT实现,默认懒加载,除非强制关掉了懒加载。另外配置文件里也可以写fetch mode,例如指定一个one-to-many的fetch mode

虽然跟Fetch不直接相关,还是讲一下NH的multi-query和Future。前者是一次执行多个query(作者这里的例子还是使用Criteria API,HQL的话可以直接写多个query,Linq的话不知。。。)。后者是真正访问数据的时候才执行SQL(不知道NH3.0的Linq实现没有,反正2.1.2时根本没实现Future方法)

二级缓存

EF不内建二级缓存。可以通过实现一个ProviderFactory来插入自己的二级缓存管理。

NH内建了一些二级缓存的provider,也有第三方实现。NH会缓存三种东西:entities、queries、timestamps。配置上和runtime可以控制是否使用cache。注意NH的二级缓存的生命周期是跟着SessionFactory走的。

Self-tracking entities

EF独家支持Self-tracking。编辑器会为你实现IObjectWithChangeTracker(这种模型也好意思叫POCO。。。作者也介绍了一种更POCO的办法,让本应属于DAL的这部分逻辑分离,看得我很orz)

NH可以使用SaveOrUpdateCopy方法,但是实际上是一个两步操作,而不像EF一样是一步操作。(在NH3.1中这个方法已经被标记为Obsolete,请改用Merge。而且NH的级联设置里为啥没有merge这个选项乜?)

Queries

EF支持两种检索方式:Entity SQL Language(相当于NH中的HQL,不过不知能力如何)和普通的Linq to Entities。另外,也可以使用precompiled表达式。

NH支持Criteria API,HQL,Linq(2.x时代是基于Criteria,3.0之后基于HQL),QueryOver(Criteria的包装)(实际上好像NH3支持7中query方式?)另外提一句multi-queries和Future。

最后,还是向大伙推荐一下国产优化框架:CYQ.Data 数据框架

新浪微博粉丝精灵,刷粉丝、刷评论、刷转发、企业商家微博营销必备工具"

2011/9/9 23:46:27 | Nhibernate3教程 | |

#2Anonymous[Register][202.104.194.*]2016/9/30 11:47:17
我从java过来的做web还是java的SSH比c#的EF+MVC+spring.net爽,因为c#的controller与view的数据传递没有Struts做得好,一开始很恶心 这是实话
#1Anonymous[Register][27.42.153.*]2012/12/22 18:57:52
迷茫!.................
  • 发表评论