NHibernate 与 EF 4.1+ [关闭]

Posted

技术标签:

【中文标题】NHibernate 与 EF 4.1+ [关闭]【英文标题】:NHibernate vs. EF 4.1+ [closed] 【发布时间】:2012-06-12 19:01:30 【问题描述】:

我正在尝试主要在这方面决定 2 ORM 的优缺点。

    与 Sql Server 2008 R2 和 2012 的兼容性。 这非常重要,因为我们根本没有资源来调试对现有 MS 技术堆栈的不良支持。 此外,自 2012 年以来的提前计划已经基本结束,并且已经制定了迁移到该计划的计划。 支持 .NET 4.0 和 4.5(即将推出) 同样非常重要,原因与上述几乎相同。 事务处理和表提示,例如。 forcescan forceeek,读取未提交。 很多时候查询优化器都能很好地完成工作,但有时我希望灵活地告诉它该做什么。 支持对话、自我跟踪附加和分离 这有点基本。我讨厌长时间保持会话开放。尤其是在分布式计算/网络农场环境中。 能够在不破坏数据的情况下处理代码优先开发、创建和更新架构。 EF 4.1 似乎在这方面有所欠缺,尽管 4.3 的飞跃性更好。也比 NH 中的单独映射类更喜欢数据注释。原因是我希望能够在类中发送,并且能够在不扩大映射类方法的情况下创建持久性模型。 支持 IRepository 模式 支持 LINQ 与上面的 (6) 有点关联,我希望对 linq 有很好的支持。我不希望开发人员在较低级别的实现中胡闹,并让自己陷入一种特定的 ORM 性能 支持批量 CRUD 操作,无需将数据加载到应用层。例如。我想将特定表的列中的所有行增加 1。我不想将其加载到内存中,并逐行递增。对于如此简单的操作,这将是疯狂的。 Linq2Sql 以前有 Magiq 来处理这种事情,NH 和 EF 有什么? 缓存、预加载、延迟加载、导航属性。 坦率地说,我讨厌这些含蓄地做的事情。原因是很难区分缓存的内容、陈旧的内容和新的内容。在 EF 中,我通常会删除所有导航属性,因为我不希望这些属性与前 5 名一起加载,因为这是当前操作所需要的,但在流的更下游,另一个开发人员会尝试进行不准确的计数。 所以我的个人政策 - 所有 SOA 都应该是无状态的,除非有充分的理由。如果您需要引用数据,请从持久性中获取。它会更慢,但代码会更具可读性和灵活性。 同样用于缓存。它在分布式环境中足够复杂,我希望所有缓存都非常明确。如果开发人员想要针对缓存编写代码,则应该这样做,而不是针对 ORM 编写代码,并使其看起来好像是从持久性中提取新数据,而实际上他正在获取陈旧数据。 现在的问题是,NHibernate 是否有任何概念/抽象可以使缓存、急切/延迟加载比 EF 中当前可用的更明确得多。在这种情况下,我不太关心开发的难易程度,我更关心的是清晰度和明确性。

另外,我不太关心 OSS 与专有论点。团队没有时间去窥探底层代码并开始弄乱其他人的代码。我更关心“它只是工作”的角度。

【问题讨论】:

写得很好的问题,虽然我担心这对 SO 来说有点开放;这里的问题通常/经常有一些源代码,并且应该导致清晰,实用的答案。也许它更适合 Programmers.SE? 【参考方案1】:

虽然我在another question 中写过其中一些问题,但我认为值得逐点回答。

    两者都与所有 SQL Server 版本兼容 两者都与 .NET 4.x 兼容。 NH 的目标仍然是 3.5,这不是问题。 两者都有事务处理。两者都不支持原生查询语言中的查询提示,但都允许您使用 SQL。 两者都允许您重新连接断开的实体。我个人认为这不是一个好的做法(我更喜欢传递 DTO) 架构迁移在 EF 中更加成熟和灵活。映射在新罕布什尔州更好。它确实支持使用属性进行映射,这比 EF 的等效功能强大得多,您很快就会发现它甚至不支持基本的东西(例如指定小数字段的精度) 您可以在任何一个之上实施您的存储库。 两者都支持 LINQ。 EF 支持更广泛的查询,但有时会产生效率极低的查询。你不应该降低你的开发实践;每种查询方法都有其优点,优秀的开发人员应该知道这些选项。 NH 的性能通常更好,因为它具有映射灵活性以及对批处理、缓存和 DML 语句的支持 EF 不支持批量 (DML) 操作。 NH 确实如此,使用与 SQL 非常相似的 INSERT/UPDATE/DELETE 语句,但基于对象模型(例如,您可以使用点语法而不是显式连接来指定条件) EF 不支持缓存,期间。有一些不受支持的样品尚未准备好投入生产。 NHibernate 中的所有缓存都是显式的(您指定要缓存的实体、集合和查询,多长时间等)。它支持像 memcached 这样的分布式缓存,因此它也可以处理过时的缓存数据。 两者都允许您显式地预先加载引用和集合。在我看来,NH 有一个更好的代理设计,它不会用 FK 污染你的模型(这是一个很长的话题,如果你愿意,你可以发布一个后续问题)。和往常一样,在指定必须如何加载每个关系时,您确实有更大的灵活性。

简而言之:NH 更灵活,性能更好,毫无疑问。 EF 具有更好的迁移支持、更简单的学习曲线和更完整的 LINQ 提供程序。

【讨论】:

很多很好的答案,但我发现这个答案是最客观和最相关的问题。谢谢。【参考方案2】:

首先,我在各个方面都比较喜欢NHibernate。 Entity Framework 在 5.0 版中也遗漏了一些东西。

    在 NHibernate 中添加新类型非常容易,因此如果 SQL Server 2012 有新类型,您可以实现相关方言/提供程序,但社区始终在工作 我知道 NH 团队正在努力支持 FW 4.5,EF supports 从 5.0 开始 使用 NH,您可以为所欲为 NH 支持 Merge 方法重新附加实体,EF 也支持 EF 不支持命名约定,NH 支持,我也在写一个基于 DataAnnotations 的自动映射器,here 旧版本的链接,等待 2 周的新版本 使用 NH 或 EF,您可以使用存储库和工作单元模式实现数据层,我还要在 NuGet 上发布这个包 EF 完全支持 LINQ,NH 不支持,但您可以使用扩展 point 进行修补 我觉得性能差不多,NH更好地支持二级缓存,所以很容易防止对数据库的命中 NH 有改进的批处理 support,我不知道 EF(特别是 5.0) NH 具有更好的扩展点实现,因此代理/缓存/日志记录比 EF 更强大,但在 EF 中您可以编写 wrapper 来获得所需的内容

最后,使用 NH 更容易实现 DDD 模式,因为映射更灵活。

【讨论】:

NH 映射如何更灵活?我发现 EF 4 fluent API 非常灵活,尤其是因为它的定义与实体类分开。 @MatteoMigliore 我喜欢你提出的包装器支持,这真是太好了!但是,是的,请说明 NH 比 EF 更灵活的原因是什么? EF 几乎允许您修改 edmx 并以您认为合适的方式进行映射,首先从代码开始。 NH 中的映射可以通过多种(多种)方式进行。 Read Fabio Maulo 关于映射的帖子。有兴趣可以等我的基于DataAnnotations的auto mapper包来快速切换NH和EF,反之亦然。 @MatteoMigliore - 我对您的自动映射器很感兴趣,它可以替代 Fluent NHibernate。你能指出我的文档,或者带有简单代码示例的博客文章吗? @TomBushell 我在Nuget 上发布了一个旧版本。我将在两周内发布新版本,改进了自动映射所有内容并与 DDD 一起使用,等待它您也可以尝试 Fabio Maulo 的ConfOrm。【参考方案3】:

你可以使用 bltoolkit ;) -> http://www.bltoolkit.net/Doc.Linq.ashx

只需花 2 分钟时间阅读此内容 -> http://www.bltoolkit.net/Doc.LinqModel.ashx

但总之

非常好的 Linq 支持 DML 操作 (nr 9) 出色的性能/批量支持 生成的 Sql 非常棒 枚举支持 ;-) 没有延迟加载/实体跟踪/特殊的魔法缓存,你现在这些东西通常会导致问题 没有神奇的功能 -> 更少的抽象 -> 更少的泄漏 -> 更少的麻烦 -> 更小的学习曲线

顺便说一句,它确实是 nr 3,它具有属性 TableFunction 和 TableExpression 以支持表值 UDF、提示和其他围绕表装饰。 因此,您可以编写自己的扩展方法以在 Linq 语句中使用 例如

[TableExpression("0 1 WITH (TABLOCK)")]
public Table<T> WithTabLock<T>()
    where T : class 

    return _ctx.GetTable<T>(this, ((MethodInfo)(MethodBase.GetCurrentMethod())).MakeGenericMethod(typeof(T)));

然后

using (var db = new TestDbManager())

    var q =
        from p in new Model.Functions(db).WithTabLock<Parent>()
        select p;

    q.ToList();

DML 操作示例

  db.Employee
    .Where(e => e.Title == "Spectre")
    .Set(e => e.Title, "Commander")
    .Update();

【讨论】:

【参考方案4】:

你不想要它们中的任何一个。您将无法指定任意表格提示,并且它不会像您希望的那样灵活。

如果所有这些都是要求,那么地球上没有 ORM 可以满足这些要求。

编辑:

根据您的评论。 nHibernate 将为您提供最强大的功能,但代价是设置模型的复杂性增加。有一些工具可能会有所帮助,但每种工具都有其优点和缺点。

EF 更易于配置和使用,但功能较弱。 nHibernate 正好相反。您必须在功能和复杂性之间做出选择。

顺便说一句,关于批量操作和其他操作,您可以直接从框架中为此类操作发出 SQL。或者调用存储过程。

【讨论】:

不,我将选择 2 个邪恶中最小的一个。这么说吧。 谢谢,但我需要详细信息。我讨厌令人讨厌的复杂性,我需要证实为什么存在复杂性的论据。以上是我寻找的东西我想知道复杂性将如何帮助我实现这个目标。 @Alwyn - 我不太明白你的意思。您需要证实为什么存在复杂性的论据?它在那里,因为这就是他们建造它的方式。 nH 随着时间的推移而发展和演变,并且它的大部分早期实践都是向前发展的。他们本可以以类似于 EF 的方式构建 nHibernate,但他们没有,唯一的原因是因为他们总是按照他们的方式来做。已经有许多尝试将 nH 带入现代配置机制,其中一些甚至在核心 FW 中获得了一些控制。最后,虽然。可配置性 = 复杂性。 @Alwyn - 问为什么某事是这样是没有建设性的,它就是这样。问题是您是否愿意按原样使用它。 nH 为您提供了很大的灵活性,但是您将要编写大量的 XML,或者尝试使流利的 nH 工作。或任何数量的其他副项目。 请不要对我的回复感到生气,感谢您的时间和回复,但我一直在寻找与上述 Matteo 的回答类似的更多逐点比较。我没有遗留系统,我只想知道哪些框架更能满足我的需求。上面详细说明了这些需求。 p.s.我不希望开发人员直接编写 sql,这违背了拥有 ORM 的意义。【参考方案5】:

只是添加到其他答案...

Ricardo Peres 前几天写了一篇非常不错的,不偏不倚的 NHibernate 和 Entity Framework 比较。它可能会对您的研究有所帮助。

你可以在这里找到它:http://weblogs.asp.net/ricardoperes/archive/2012/06/07/differences-between-nhibernate-and-entity-framework.aspx

【讨论】:

以上是关于NHibernate 与 EF 4.1+ [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

Entity Framework 4.1 和 NHibernate 的获取策略封装

csharp: NHibernate and Entity Framework (EF) (object-relational mapper)

相当于NHibernate中Hibernate的@embeddable/EF的ComplexTypeConfiguration?

用 LINQ to SQL 或 LINQ to EF 替换 NHibernate

与 ObjectContext 相比,为啥在 EF 4.1 中插入实体如此缓慢?

ADO.NET 实体框架与 NHibernate [关闭]