实体框架与 NHibernate - 性能
Posted
技术标签:
【中文标题】实体框架与 NHibernate - 性能【英文标题】:Entity framework vs NHibernate - Performance 【发布时间】:2013-08-01 15:42:11 【问题描述】:我希望在我们的系统中实现 ORM。我们目前有许多表,其中包含大量可怕的数据和存储过程。我听说使用 ORM 会减慢系统速度。有谁知道使用 C# 代码中创建的查询并映射到存储过程,哪个 ORM 在速度和性能方面更好?
谢谢
编辑:
该项目将使用包含大量数据的大型现有表,还将使用在 SQL Server DB 中执行复杂任务的现有存储过程。 ORM在运行现有存储过程和查询当前表时必须能够执行事务并具有高性能。该项目是基于 Web 的,将使用带有 DDD 的 WCF Web 服务。我可以看到 EF 更容易使用并且有更大的支持,但如果 NH 是最合适的选择?
【问题讨论】:
我们谈论的项目有多大?几百个查询,几千个?您是否在抢先优化?没有什么比直接查询或像 Dapper.NET 这样快的了,但仍然可以根据您的编码方式合理使用。 看看以下:***.com/questions/699792/is-orm-slow-does-it-matter @Paddy 是的,但在 EF4 和 EF6 之间有很多变化 NHibernate > 实体框架。甚至不值得考虑 EF。 请记住,使用 ORM 时,性能主要取决于您编写查询的方式。我看到很多人告诉我 ORM 很慢,当我查看他们测试它的方式时,我立即明白出了什么问题!context.Customers.Include("Orders").Include("OrderLines").Include("Products")
;-)
【参考方案1】:
check this artical NH 相对于 EF 的一些优势
-
NH 有 10+ id generator 策略(IDENTITY、sequence、HiLo、manual、increment、几个 GUID 等),EF 只有 manual 或 SQL Server 的 IDENTITY;
NH 具有惰性属性支持(注意:不是实体,这是用于字符串、XML 等属性),EF 没有;
NH 具有二级缓存支持(相信我,企业开发人员正在使用它)而 EF 没有;
NH 支持具有“虚拟”属性的自定义类型,甚至是复杂类型,其中包括查询这些虚拟属性,而 EF 不支持;
NH有公式属性,可以是任何SQL,EF不行;
NH 具有实体和集合的自动过滤器,而 EF 没有;
NH 支持原始类型(字符串、整数等)以及组件(没有标识的复杂类型)的集合,而 EF 不支持;
NH支持6种集合(list、set、bag、map、array、id数组),EF只支持一种;
NH 包含一个代理生成器,可用于自定义生成的代理,EF 不允许这样做;
NH 有 3 个映射选项(.HBM.XML,按代码,按属性),而 EF 只有两个(按属性,按代码);
NH 允许查询和插入批处理(这是因为 EF 仅真正支持 IDENTITY 键),EF 不支持;
NH有几种乐观控制策略(db上的列,包括Oracle的ORA_ROWSCN,timestamp,integer version,all,dirty columns),EF只支持SQL Server的TIMESTAMP或者all
【讨论】:
【参考方案2】:实体框架不断实现新功能,并且您的项目中的一切都是自动化的。使用实体框架,扩展和重构代码非常容易。 Visual Studio 像魅力一样集成了它(代码优先、数据库优先、实体优先……)。 Windows Azure 使其易于部署和更改。 此外,Visual Studio 可以在 3 次点击中生成所有 CRUD 页面。
我建议您使用 EF,但这取决于您的项目。你能告诉我们更多的细节吗?
您可以在 Google 上找到很多比较图表,例如 this one 解释性能和 this one 差异。
编辑:
您能否量化应用程序中的用户数量?
当您在 EntityFramework 中使用 Database-First 时,import and use stored procedures 非常容易,NHibernate 也很容易使用 quite simple。 请注意,如果您使用大量存储过程而不是大量同时使用的用户,那么在这两者之间选择 ORM 可能不是那么重要。
另外不要忘记,工具的性能通常取决于使用它的方式。如果您滥用 ORM(例如异步、延迟/急切加载、基类等),性能将急剧下降。
也许您可以同时安装它们,查看它们的工作方式并查看其路线图(例如Entity framework)以查看演变和兴趣。
【讨论】:
使用 Fluent NHibernate 无需创建映射文件! 是的,感谢您发现这一点,我正在开发旧项目,目前 Fluent NHibernate 还不存在,所以我必须手动创建映射。【参考方案3】:两者都是很好的解决方案,尽管我个人认为 NHibernate 更适合继承数据库。
NHibernate 有一些明显更好的东西,比如二级缓存支持。文档可能比 EF 少一些,但如果您愿意经历学习曲线,NHibernate 会为您提供更多功能。
FluentNHibernate 非常适合将类类型化映射到基础表,但有些地方您只需要恢复为 XML 映射即可。然而,NHibernate 本身有一个新的竞争 API,我还没有检查过(上面的博客文章提到了它)。
如果你想依赖 VS 工具支持,EF 更好。但是有时会有一些魔法(例如,EF 可以使用反射来填充对象的私有属性,NHibernate 不会这样做;这取决于您如何看待它,这是一种优势或劣势)。 EF 也适用于其他 Microsoft 提供的框架(例如 RIA 服务)。我也喜欢 EF 自动迁移(当您使用代码优先时)。
如果您希望掌握更多权力,并且希望能够通过明确的关注点分离来微调事物的工作方式(ORM 只做 ORM 应该做的事情),NH 似乎更好。但是,让 NH 能够访问它们的所有属性都是虚拟的,这有点烦人。
这两种方法我都用过,但有时生成你想要的 sql 会有点笨拙;在那些 5-10% 的情况下,再下降一个级别并使用像 Dapper、Massive 或 Petapoco 这样的微型计算机。
编辑:
NHibernate 似乎也可以填充私有属性,所以这只是我的无知。
【讨论】:
【参考方案4】:.NET 4.5 上的 EF 5 或 6 是提高性能的一种可靠方法,不要指望 .NET 4.0 上的 EF 5 有任何速度改进,这是由 Microsoft 记录的。 (我们还有另一个问题是 LINQ 语句写得不好)。
一般来说,如果性能是高优先级,则无法通过存储过程击败 ADO.NET。你根本做不到。添加了 ORM,添加和 IOC 容器...您要进行多少性能测试?
使用 JMETER 启动几个 VM,然后使用 EF 访问服务器并使用 NHibernate 访问另一个服务器,您只需强制 JMETER 对 URLS 进行足够多的调用并测试并发用户的数量,您应该会看到瓶颈在哪里。
【讨论】:
存储过程对简单的 select 语句没有更多优势,因为所有现代 DBMS 都可以记住正确参数化的 SQL 查询并使用相同的查询计划执行它们,就像存储过程一样。如果您需要过程元素,例如循环、控制元素、变量等,存储过程是很好的选择。 究竟什么是简单的选择语句。 “从我的 simpleTable 中选择 simple1、simple2”?那么,如果该表有 1000 万行呢?根据定义,这是一个“简单的选择语句”,但是后端表非常庞大,那么通常最好放入一个 proc。我喜欢 linq 语句,但是每个人都用 linq 语句替换 sprocs 的整个趋势最终并没有被证明是明智的。许多网站都在爬网,必须付出很多努力才能修复。 浏览量胜过数据访问的价格。然后。你在视图上使用 ef 并且仍然获得可组合性。【参考方案5】:这里值得补充的是,Entity Framework 在附加断开连接的图时存在问题,并且缺少 Nhibernate 中的合并等功能。您可以使用其他插件解决它,但不是开箱即用。这是 Codeplex 上的功能的link,请求更好地支持处理断开连接的实体,还有一些进一步的讨论。
【讨论】:
EF 中缺少 .Merge 对某些人来说是一个交易破坏者。 OP应该对此进行研究。 “实体框架合并”。谷歌或必应。你会看到大的 snapfu。以上是关于实体框架与 NHibernate - 性能的主要内容,如果未能解决你的问题,请参考以下文章
使用 nHibernate 选择具有许多子集合的实体的性能不佳