NHibernate与EF 4.1+

时间:2012-06-12 19:01:30

标签: .net entity-framework nhibernate orm fluent-nhibernate

我试图主要在这个领域决定2 ORM的利弊。

  1. 与Sql Server 2008 R2的兼容性& 2012。
    • 这非常重要,因为我们根本没有资源来调试对现有MS技术堆栈的不良支持。
    • 自2012年以来,提前计划已经完成,并计划迁移到它。
  2. 支持.NET 4.0和4.5(即将推出)
    • 再次非常重要,原因与上述相同。
  3. 交易处理和表格提示,例如。 forcecan forceseek,读取未被发现。
    • 很多时候,查询优化器能够很好地完成工作,有时候我希望能够灵活地告诉它该做什么。
  4. 支持对话,自我跟踪附加&分离
    • 这有点基础。我讨厌长时间保持会议开放。特别是在分布式计算/ Web场环境中。
  5. 能够处理代码首先开发,创建和更新架构而不会破坏数据。
    • EF 4.1在这方面似乎很缺乏,尽管4.3越来越好。也比NH中的单独映射类更喜欢数据注释。原因是我希望能够在类中发送,并且能够在不扩展映射类的方法的情况下创建持久性模型。
  6. 支持IRepository模式
  7. 支持LINQ
    • 与上面的(6)有点关系,我希望对linq有很好的支持。我不希望开发人员使用较低级别的实现并让自己陷入某个特定的ORM
  8. 性能
  9. 支持批量CRUD操作,无需将数据加载到应用程序层。例如。我希望将特定表的列中的所有行递增1.我不想将其加载到内存中,并逐行递增行。这对于这样一个简单的操作来说会很疯狂。 Linq2Sql过去常常让Magiq处理这类事情,NH和EF有什么作用?
  10. 缓存,急切加载,延迟加载,导航属性。
    • 坦率地说,我坦白地讨厌这些事情。原因是很难区分什么是缓存,陈旧和新的东西。在EF中,我通常会删除所有导航属性,因为我不希望这些属性加载前5,因为这是当前操作所需要的,但是在流的下游,另一个开发人员尝试进行计数,这将是不准确的。
    • 所以我的个人政策 - 除非有充分的理由,否则所有的SOA都应该是无国籍的。如果需要引用数据,请从持久性中获取数据。它会更慢,但代码更具可读性和灵活性。
    • 同样适用于缓存。它在分布式环境中足够复杂,我希望所有缓存都非常明确。如果开发人员想要对缓存进行编码,它应该这样做,而不是针对ORM编写代码,并使其看起来好像他正在从持久性中提取新数据,而实际上他正在获取陈旧数据。
    • 现在的问题是,NHibernate是否有任何概念/抽象可以使缓存,急切/延迟加载比EF中当前可用的更加明确。在这种情况下,我不太关心开发的容易程度,我更关心清晰度和清晰度。
  11. 另外,我并不关心OSS与专业论证。团队没有时间窥视引擎盖并开始搞乱其他人的代码。我更关心“它只是工作”的角度而不是其他任何东西。

5 个答案:

答案 0 :(得分:10)

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

  1. 两者都兼容所有SQL Server版本
  2. 两者都与.NET 4.x兼容。 NH仍然以3.5为目标,这不是问题。
  3. 两者都有交易处理。既不支持本机查询语言中的查询提示,但都允许您使用SQL。
  4. 两者都允许您重新附加断开连接的实体。我个人认为这不是一个好习惯(我更喜欢传递DTO)
  5. 模式迁移在EF中更加成熟和灵活。 NH的映射方式更好。它确实支持使用属性进行映射,这比EF的等效功能更强大,你很快就会发现它甚至不支持基本的东西(比如指定十进制字段的精度)。
  6. 您可以在任何一个上实现您的存储库。
  7. 两者都支持LINQ。 EF支持更广泛的查询,有时会产生极其低效的查询。你不应该愚弄你的开发实践;每个查询方法都有其优点,一个好的开发人员应该知道这些选项。
  8. NH的性能通常更好,因为它具有映射灵活性并支持批处理,缓存和DML语句
  9. EF不支持批量(DML)操作。 NH使用INSERT / UPDATE / DELETE语句与SQL语句非常相似,但是在对象模型上(例如,您可以使用点语法而不是显式连接来指定条件)
    • EF不支持缓存,期间。有一些不支持的样品尚未准备好生产。 NHibernate中的所有缓存都是显式的(您指定要缓存的实体,集合和查询,持续多长时间等)。它支持像memcached这样的分布式缓存,因此它也可以处理过时的缓存数据。
    • 两者都允许您明确地加载引用和集合。在我看来,NH有一个更好的代理设计,它不会用FK污染你的模型(这是一个很长的话题,如果你愿意,你可以发布一个后续问题)。和往常一样,在指定必须如何加载每个关系时,你会有更多的灵活性。
  10. 简而言之:NH更灵活,表现更好,更容易实现。 EF具有更好的迁移支持,更简单的学习曲线和更完整的LINQ提供程序。

答案 1 :(得分:8)

首先,我更喜欢NHibernate的各个方面。实体框架也在版本5.0中遗漏了一些内容。

  1. 在NHibernate中添加新类型非常容易,因此如果SQL Server 2012有新类型,您可以实现相对的方言/提供者,但社区始终在工作
  2. 我知道NH团队正在努力支持FW 4.5,EF supports来自5.0
  3. 使用NH,你可以做你想做的一切
  4. NH支持Merge方法重新附加实体,EF也
  5. EF不支持命名约定,NH也支持,我也在编写基于DataAnnotations的自动映射器,here指向旧版本的链接,等待2周新的
  6. 使用NH或EF,您可以使用存储库和工作单元模式实现数据层,我还将在NuGet上发布此包
  7. EF完全支持LINQ,NH,但您可以使用扩展名point
  8. 进行修补
  9. 我认为性能处于同一水平,NH更好地支持二级缓存,因此很容易防止命中数据库
  10. NH有一个改进的批量support,我不知道EF(特别是5.0)
  11. NH有更好的扩展点实现,因此代理/缓存/日志比EF更强大,但在EF中你可以写一个wrapper来获得你需要的东西
  12. 最后,使用NH更容易实现DDD模式,因为映射更灵活。

答案 2 :(得分:6)

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

只需2分钟即可阅读 - > http://www.bltoolkit.net/Doc.LinqModel.ashx

但总之

  • 非常好的Linq支持
  • DML操作(nr 9)
  • 卓越的性能/批量支持
  • 很棒的生成Sql
  • enum support; - )
  • 没有延迟加载/实体跟踪/特殊魔术缓存,你现在这些通常会导致问题的事情
  • 没有神奇的功能 - >减少抽象 - >减少泄漏 - >少麻烦 - >较小的学习曲线

btw它的确是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();

答案 3 :(得分:1)

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

如果所有这些都是要求,那么这个星球上就没有符合它们的ORM。

编辑:

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

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

BTW,关于批量操作以及什么不是,您可以直接从框架发出SQL来进行此类操作。或者调用存储过程。

答案 4 :(得分:1)

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

几天前,

Ricardo Peres写了一篇关于NHibernate和Entity Framework的非常好的,无偏见的比较。它可能对你的研究有所帮助。

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