实体框架4与NHibernate [关闭]


114

在网络上(以及在stackoverflow上)已经谈论了很多关于Entity Framework第一版的问题,很明显,当我们已经有了更好的替代方案(如NHibernate)时,这不是一个好选择。但是我找不到Entity Framework 4和NHibernate的很好比较。可以说,今天NHibernate是所有.NET ORM的领导者,但是我们可以期望Entity Framework 4取代NHibernate。我认为,如果Microsoft确实在EF4中注入了非常好的功能,则它可以与NHibernate竞争,因为它具有Visual Studio集成,易于使用并且在大多数商店中总是优先考虑MS产品。


31
我想要此比较的更新。自09年以来发生了很多事情吗?
菲尔

Answers:


66

EF4在“自我跟踪实体”中就n层开发提供了开箱即用的答案。没有人发布过类似的NHib代码。

NHib具有许多未被提及为EF4的功能。这些包括二级缓存集成。它还在继承映射方面具有更大的灵活性,可以与存储的proc /数据库函数/自定义SQL /触发器更好地集成,对公式属性的支持等等。IMO作为ORM基本上已经成熟了。


13
+1你是对的。NH才刚刚成熟。EF将于今年年底赶上来。4.0版已经有了引人注目的入口。给它一些时间,这将是防弹的2011年中期

15
-1对于“ EF4在“自我跟踪实体”中对n层开发具有开箱即用的答案。没有人发布过类似的NHib代码。” NHibernate中有ISession.Merge,它由于N-Tier开发而比自跟踪实体要好得多,原因很多。
Alex Burtsev 2011年

12
@Alex-NHibernate以什么方式成为“开箱即用”的解决方案?只是为了澄清;“开箱即用”意味着它可以与Visual Studio的原始安装一起使用。那是不合理的-1。
琼斯医生

9
@DoctaJonez-在我的阅读方式中,Alex质疑NH不能与自我跟踪实体相提并论的想法,而不是关于它是“开箱即用”的部分。
耶夫(Jerph)2011年

2
实际上,我发现EF4具有更灵活的继承映射。例如,您可以将2个表(TPT)用作基类+ 1级类,并将鉴别符添加到1级表中,从而允许拆分为2级类。在NH中,区分词只能在基类上定义。
Danny Varod 2011年

37

更新:我从4.0版开始就没有使用Entity Framework,所以我的答案可能已经过时。我仍在项目中使用NH或纯ADO .NET。而且我什至不想看自4.0以来EF中的新增功能,因为NH可以完美地工作。

当您同时使用它们时,将它们进行比较实际上很容易。EF4有一些严重的局限性,我可以列举一些我自己遇到的问题:

EF4问题:

  • 急于加载并调整结果:EF4急于加载系统(Include(“ Path”))生成不正确的SQL,并带有JOIN循环,对于多对多关系,这将执行数千个(不是字面上的)时间,然后是手写SQL(实际上无法使用)。
  • Materializer无法实现关联的实体:如果您认为可以通过提供自己的SQL查询来解决先前的问题,那您是错的。EF4无法从JOIN SQL查询中实现(映射)关联的实体,它只能从一个表中加载数据(因此,如果您有Order.Product,SELECT * FROM order LEFT JOIN Product将仅初始化Order对象,Product将保持为空,以为所有必要的数据都在查询中获取以初始化它)。这可以通过使用EFExtensions社区插件来克服,但是为此您必须编写的代码非常丑陋(我尝试过)。
  • 自我追踪实体:许多人说,自我跟踪实体对于N层开发很酷,包括此线程中的最佳答案。以为我什至没有尝试,我可以说他们没有。每个输入都可以伪造,您不能简单地接受用户发送给您的更改并将其应用于数据库,为什么不给用户直接数据基础访问呢?您将必须从数据库中更改数据用户的任何方式都将要更改,检查其是否存在|不存在,进行权限检查等。您无法相信用户正在发送给服务器的实体的状态,无论如何必须从数据库加载此实体并确定其状态等信息,因此该信息是无用的,就像自我跟踪实体一样,除非您为内部使用做一个私有的受信任的n层系统,在这种情况下,您可以简单地给出数据库访问。

  • 日志记录,事件,集成业务逻辑: EF4就像黑盒子一样,它可以执行某些操作,而您不知道它会执行什么操作。只有一个事件OnSavingChanges,您可以在其中发生一些业务逻辑,以便在DB发生某些事情之前将其运行;如果您需要在发生某些事情之前对业务对象应用一些更改,则必须在ObjectStateManager中进行挖掘,这确实很丑陋,代码可能会变得巨大。例如,如果您使用存储库模式以及以干净对象方式通知数据库更改的内容,您将很难使用EF。

  • 可扩展性:所有EF代码都是私有的和内部的,如果您不喜欢某些东西(如果您认真对待EF,则不会喜欢LOT),那么您绝不可能以简单的方式更改它,事实上,我敢肯定从头开始编写自己的ORM(我做到了),然后根据需要使EF工作变得容易。例如,请看一下EFExtensions的源代码,它基于扩展方法和不同的“ hacks”,使EF更加有用,并且代码非常丑陋(这不是作者的错,当EF中的所有内容都是私有的时,这是唯一的)扩展方式)。

我可以继续写关于EF的坏东西,而使用它工作20多个页面对我来说是多么痛苦,也许我会的。

NHibernate呢?这是绝对不同的水平,就像将PHP与C#进行比较,EF4就像在Stone-age中一样,就像EF比NHibernate落后10年,而Hibernate实际上是在2001年启动的。如果有空的话要学习并打开Nhibernate,请执行此操作。


1
EF已根据Apache 2许可发布,这将有助于扩展性。
CMircea

@MirceaChirea那是个好消息,我没想到,现在浏览EF源代码,非常有趣。
亚历克斯·伯采夫

2
-1表示前面有几条陈述:“我没用过,但我还是在说。”
Kyeotic

@Tyrsius我的答案是在大约3年前写的,我已经很长时间没有使用EF了,有些事情可能会有所改善,您可以编辑我的答案以更新为当前的EF状态。
Alex Burtsev

2
您承认您从未使用过自我跟踪实体,但是却将其关闭。仅讲您所知道的内容,而忽略无知的猜测,尤其是因为整个段落都非常错误。
汤姆·哈拉迪

25

就是这个 在我看来,NHibernate和Entity Framework确实适合两个不同的受众。在构建具有复杂映射,公式和约束(基本上是任何企业)的系统时,我会选择NHibernate。如果我想通过简单的数据访问来开始运行,那么可以使用Entity Framework或LINQ-to-SQL。NHibernate没有像EF一样清晰的“拖放”体验。两者都有其优点和缺点。坦率地说,将它们进行比较,无济于事。


13
您是否尝试过ActiveWriter?实体框架绝对针对企业空间。我不同意您的大部分意见。
Michael Maddox

1
不满足您的所有想法,但是NHibernate已经存在很长时间了,这是企业不容忽视的事情。
zowens 2009年

21
-1这不是NHibernate与Entity Framework的很好的比较。通过将EF与LINQ集成到SQL中来比较两者,b / c充其量只能说是轻率的。就复杂性而言,NHibernate到底能做到EF 4不能做什么?
凯文·巴布科克

14
二级缓存,其查询经过高度优化,NH强制您使用UnitOfWork模式,而且映射不会卡在一个文件中。我的观点(根据经验)是NHibernate的性能更高。对此我不同意,但是我确实说那是我的观点。我的回答是仍然有效,它们都有优点和缺点。没有人可以否认这一点。
zowens

2
@ MakerOfThings7太可悲了...整个问题都是主观的。醒来...
zowens

23

如果您认为自己可能想在Mono上运行代码,那么无论功能清单如何,NHibernate可能都是一个更好的选择。

编辑,2012年8月13日:

实体框架已经开源,现在从2.11.3开始包含在Mono中。现在,这个答案已经过时了,不应被依赖。

http://weblogs.asp.net/scottgu/archive/2012/07/19/entity-framework-and-open-source.aspx


实际上,从mono-project.com/Compatibility读取为“ EntityFrameworks-Not available。”,并且似乎没有人对实现它感兴趣。因此,至少几年来,它还是NHibernate或什么也没有。
user276648 2011年

12

我对此的看法是,EF4.0自1.0版以来已经走了很长一段路,并在功能上赶上了Nhibernate,但还不止这些。

但是,它是Microsoft的现成产品,可以完成95%的应用程序所需要的100%的工作。但是,NHibernate多年来一直在做同样的事情。版本5.0或6.0可能会赶上,甚至超过NHibernate。

这是我的建议-如果您有时间学习两者,那就去做。选择一个而不是另一个有几个原因。如果您正在为公司编写代码,那么期望拥有能够熟练掌握EF的员工是现实的,因为这在所有书籍中以及孩子们在大学里学到的东西都是如此。如果EF能够满足您的要求(想一想,再想一想就花点时间),那么它现在是一个完美的解决方案,并且在几年内(可能,很可能)会超过NHibernate。

NHibernate是一种非常成熟的产品,已经在EF上使用了几年,它很可能会做您想做的所有事情,然后再做一些。一段时间以来,它一直是最好的ORM,许多人都在使用它。


10

我认为EF 4具有使用POCO和延迟延迟加载的能力这一事实将非常重要。我绝对可以看到它在新版本中越来越受欢迎。


7
不要忘记LINQ支持。NHibernate仍然不擅长此事。
09年

1
@Arnis,您可以提供任何链接来支持该观点吗?
Michael Maddox

2
@Michael当您浏览有关该主题的Ayande博客文章时,这一点显而易见。LINQ to NH目前基于标准API。标准API不允许HQL可以使用某些更复杂的查询功能。LINQ to NH的下一个版本将使用HQL代替标准API。
zowens

5

与NHibernate相比,EF流行度明显上升趋势,请参见图片。

NHibernate与实体框架



根据趋势,随着时间的流逝,人们开始更多使用谷歌搜索EntityFramework。他们可能有充分的理由。也许开始变得更好。
Tomas Kubes

可能是这种情况,也可能是默认情况下被汇总为MS使用的情况。此外,EF的工具也相当不错。
的Răzvan弗拉菲乌斯熊猫

4

我的2美分:我们在台式机客户端上使用ef进行某些处理等-无负载。服务器端的NHib-利用无状态会话,hilo id生成和批处理。每秒在db中插入3k +消息是相当快的。而且它非常灵活,并支持许多数据库,这对于我们的产品至关重要。


3

使用Linq的组合将逻辑层直接映射到存储过程似乎是最简单的方法。没有xml。仅针对不太常用或不适合存储过程的有趣查询生成sql。

对象通过标准SP加载和存储。这种方法允许使用两个sql登录名。一种用于通过SP(仅执行权限)进行的类访问,另一种用于允许直接表访问的逻辑linq模块。


1

最好不要在ORM之间按流行程度进行选择。在过去的两年中,我尝试过使用EF,而我只能说,为什么我仍然会尝试呢?

我对EF的ATM观点是:“它是为不多于3个表且关系少于1个的很小的非常小的位系统而设计的(0更好)。”

我为什么这样想呢?1.尝试更新断开连接的图并查看模型的刮擦;

  1. 尝试使用具有深厚继承树的TPH进行创建,您会发现自己被束缚在单个层次结构中,否则系统将崩溃。

  2. 尝试进行更多麻烦的查询,并观察整个系统耗尽堆栈:D ...溢出经常发生。

  3. Map XML数据类型基于扩展名或最“讨厌”的NotMapped属性……甚至更糟。

  4. 尝试将SQL查询混入Linq中以获取更多查询,否则您将大笑。

  5. 最后也是最重要的一点是,EF不支持属性公式(“ NH具有用于旧数据库的大量资源”),并且不支持相同表和相关表的复杂类型映射。

那是我的10cc。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.