Entity Framework和NHibernate是当前.NET里最强大的两个ORM框架,一个是微软官方出品,一个是开源项目代表之作。我在09年用过EF 3.5,在最近的一个项目里在使用NH,虽然无可否认这两个ORM框架功能都当强大,然而我在使用过程中还是觉得许多需要吐槽的地方。
首先说说EF,其实我最早接触的是Linq To SQL,但由于当时项目的后台数据库是Oracle,而Linq To SQL只支持SLQ Server,所以它立马被否决,而其它的开源框架,一是我没有用过,不熟不敢用,二是使用Linq To SQL有一段时间了,linq用得很爽,很上瘾(相信用过的童鞋都了解),所以瞄中了这个微软刚刚出炉的EF。这个EF虽然号称支持多种数据库,但是微软仍然只内置了SQL Server的Data Provider,由于EF刚刚推出,Oracle官方还没有提供只能对EF的Provider,好在微软自己在codeplex上以Oracle 10g,11g为例,发布了一个针对Oracle的EF Data provider的示范性的开源项目。经过一番波折,总算用上EF了。在使用过程中,也发现若干不便之处,太多细节之处也记得不清了,这里列举一二。一是实体模型,即那个edmx文件,每次数据库对表或者字段作了改动,都需要重新生成一次该模型,当时的数据库表有好几百个,一次生成过程便需要几十分钟(后来EF4.1推出的code first相信便是吸取了这个教训),二便是linq To Database的 查询中居然不支持like模糊查询,(委实不知道微软的EF开发小组当时是怎么想的,后来在EF4.0才添加了这个功能),由于不支持模糊查询,在必须要模糊查询的地方不得已又用回sql,这代码写得让人非常尴尬,恶心。当EF升级到4.1时,虽然修正上述毛病,去年 Oracle也终于推出了自己的EF for Oracle 的Provider beta版,但可惜的是至今oracle 的provider依然还没能支持 fode first。当然还有一些后来在4.0改进了的地方,比如支持poco等。
NH在支持多数据库方面比EF好多了,但可惜那一大堆xml配置文件更让人崩溃,为了不用配置那一堆xml文件,找到了NH的扩展项目,NHibernate mapping attributes,然后又发现NH以及扩展项目的版本繁多,同时还有一大推相关的dll 什么common logging,log4net,总的来说就是,版本以及扩展项目较多,但文档缺乏,使用复杂,与主干NH配合使用并非是无缝连接,相对于微软的EF来说,毕竟不是商业化软件,在易用性方面差很多,更多的感觉是为了玩技术而编写出来的,没有一定的技术水平都不好掌握。以mapping attributes来说,在实体定义的特性上标注了有关数据库表的信息以后,还需要再写几行代码把这些实体序列化为流的形式提供给NH, 再如实体的定义来说,class的特性就一大堆,什么对应的数据库表名,实体的类的全名,实体的Type,实在太啰嗦了。
我认为这两个框架共同的不足是都没有使用泛型去对所有实体的CRUD作一个封装,以EF为例,生成的实体模型里提供一大堆AddToxxx方法,微软自己是泛型的缔造者,居然不提供一个 T AddTo<T>(T t),NH还好点,它的贡献子项目里后来有了使用泛型的封装。
当然我批评这两个框架的不足之处并不等于我否认其伟大之处,EF的伟大之处在于配合Linq To DB,NH听说支持linq,虽然可能不及微软的强大,但是起码支持多数据库,运行版本低(framework2.0,无须像EF那样要装个framework 3.5或者4.0),又不像EF偏食和挑剔,两者的共同突出优点我觉认为是对主从(多)表关联的支持,在网上也看过不少网友自己公布的ORM,但大多数都只是支持单表操作,说实话,那些对单表的CRUD,没有什么技术难度。但凡事有利必有弊,EF和NH对多表查询的支持力度大,也造成了使用的复杂性,比如NH的需要在xml中的实体配置中定义,比如EF必须要在数据库中定义表的外键关联,使用时还有延迟加载,即时加载,当处于远程化环境下也无法使用,提交时候是否需要事务处理等诸多复杂问题。
综上所述,我产生了要实现自己的ORM的想法,目标是简单、易用、够用。不是要建造重复的轮子,而是要建造适合自己的轮子。